Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在流套接字字节流中查找特定字符串_C - Fatal编程技术网

C 如何在流套接字字节流中查找特定字符串

C 如何在流套接字字节流中查找特定字符串,c,C,我是C新手,在这里遇到了一点小麻烦,我试图解析一个html文件,并计算文件中的p标记数。我使用不同大小的块,大小由用户输入。但是当尺寸跳到200时,我得到了错误数量的p标签。我使用recv函数来接收一个文件,并使用缓冲区的内容来计算所述p标签 count = recv(s, buf, sizeof buf, 0); for(int i=0; i<chunk; i++) { if(buf[i]=='<') if(buf[i+1

我是C新手,在这里遇到了一点小麻烦,我试图解析一个html文件,并计算文件中的p标记数。我使用不同大小的块,大小由用户输入。但是当尺寸跳到200时,我得到了错误数量的p标签。我使用recv函数来接收一个文件,并使用缓冲区的内容来计算所述p标签

    count = recv(s, buf, sizeof buf, 0);
    for(int i=0; i<chunk; i++)
    {
        if(buf[i]=='<')
          if(buf[i+1]=='p')
                if(buf[i+2]=='>')
                pcount++;>*/
    }
count=recv(s,buf,sizeof buf,0);
对于(int i=0;i*/
}

当区块大小为200时,它应该返回13个p标签,但它返回15个。

有几个问题。推测
chunk
是缓冲区的大小。现在,如果
recv
成功,它将返回接收的字节数。您应该使用此计数而不是
chunk
来限制循环。否则,您将使用n即使是失败的
recv
操作,它也会对缓冲区中存在的任何垃圾进行计数

当然,第二个问题是,
标记实际上可能位于两个块的边界上

第三个问题是,您可能正在读取超出边界的缓冲区-即使
buf[i]
是有效的,但这并不意味着
buf[i+2]
是有效的


最简单但可能不是最正确的解决方案是在套接字上使用
fdopen
,然后使用
fgetc()
,或者将整个正文读入缓冲区。不过,让我们使用
fdopen

FILE *f = fdopen(s, "r+b");
size_t pcount = 0;

int c = 0;
while (c != EOF)
{
    if ((c = fgetc(f)) == '<' 
         && (c = fgetc(f)) == 'p'
         && (c = fgetc(f)) == '>') 
    {
        pcount += 1;
    }
}

这将在不同的块大小之间正常工作,并且不会解决缓冲区超出范围的问题。但是,与
fdopen
相比,它看起来要复杂得多,即使它仍然缺少外部循环!

什么是
chunk
?它与
rec返回的
count
有什么关系v
?当
i
等于
chunk-1
chunk-2
时,索引
i+1
i+2
是否有效?请尝试创建一个适当的索引来显示给我们。另外,请阅读,以及。最后,请。在处理文件时,我必须以字节大小由通过命令行参数向用户发送消息。Count与程序的另一部分有关,在该部分中,我返回html文件中的字节数。如果
Count
,会发生什么情况?如果使用TCP套接字,请记住没有消息边界或数据包。在单个
recv
调用中接收的数据可能小于what是在一次
send
调用中发送的,如果在调用
recv
之前缓冲了两次或两次以上的
send
调用,则发送的次数甚至更多。索引
i+1
i+2
将超出
块大小的范围。而且您甚至似乎没有检查错误,这是套接字通信。@RaqueldeAnda如果您需要使用特定的块大小,那么状态机可能就是您应该使用的
int pstate = 0;

ssize_t count = recv(s, buf, sizeof buf, 0);
// TODO: add error checking...

for (ssize_t i = 0; i < count; i++)
{
    if (buf[i] == '<') {
        pstate = 1;
    }
    else if (pstate == 1 && buf[i] == 'p') {
        pstate = 2;
    }
    else if (pstate == 2 && buf[i] == '>') {
        pcount += 1;
        pstate = 0;
    }
    else {
        // if any other character is found,
        // or any of these characters was in wrong position
        // then reset the state
        pstate = 0;
    }
}