recv 返回旧数据

发布于 2024-08-30 13:01:29 字数 578 浏览 8 评论 0原文

该循环应该从套接字逐行获取数据并将其放入缓冲区中。由于某种原因,当没有新数据返回时,recv 返回它得到的最后几行。我能够通过注释掉第一个recv来阻止该错误,但随后我无法判断下一行会有多长。我知道这不是一个

while(this->connected){
    memset(buf, '\0', sizeof(buf));
    recv(this->sock, buf, sizeof(buf), MSG_PEEK);           //get length of next message
    ptr = strstr(buf, "\r\n");
    if (ptr == NULL) continue;
    err = recv(this->sock, buf, (ptr-buf), NULL);    //get next message

    printf("--%db\n%s\n", err, buf);

    tok[0] = strtok(buf, " ");
    for(i=1;tok[i-1]!=NULL;i++) tok[i] = strtok(NULL, " ");

//do more stuff
}

This loop is supposed to take data from a socket line by line and put it in a buffer. For some reason, when there is no new data to return, recv returns the last couple lines it got. I was able to stop the bug by commenting out the first recv, but then I cant tell how long the next line will be. I know it's not a

while(this->connected){
    memset(buf, '\0', sizeof(buf));
    recv(this->sock, buf, sizeof(buf), MSG_PEEK);           //get length of next message
    ptr = strstr(buf, "\r\n");
    if (ptr == NULL) continue;
    err = recv(this->sock, buf, (ptr-buf), NULL);    //get next message

    printf("--%db\n%s\n", err, buf);

    tok[0] = strtok(buf, " ");
    for(i=1;tok[i-1]!=NULL;i++) tok[i] = strtok(NULL, " ");

//do more stuff
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

圈圈圆圆圈圈 2024-09-06 13:01:30

你的问题是,当你使用带有MSG_PEEK的recv时,你给recv缓冲区的整个大小,如果已经有两行,比如“HELLO\r\nHELLO\r\n”,它会将它们读入你的buff中。

ptr会指向第一个\r\n,然后你用(ptr - buff)调用recv,这将使recv只读取第一个HELLO,进入buf,但由于你已经将该信息读入buff,你将处理这两个行,但将 \r\nHELLO\r\n 留在队列中,因为您没有完全阅读它们。

下次您查看它时,会看到已经处理过的信息,让您相信您正在获取重复的数据。

(我希望我写得足够清楚,这是一个非常令人困惑的错误:)

Your problem is that when you use recv with MSG_PEEK, you are giving recv the whole size of your buffer, if there are two lines already there, like "HELLO\r\nHELLO\r\n" it will read them into your buff.

ptr would point to the first \r\n, then you call recv with (ptr - buff) which will make recv to read only the first HELLO, into buf, but since you already READ that info into buff, you will process the two lines, but leaving \r\nHELLO\r\n in your queue, because you did not fully read them.

Next time you would peek into it and have info hanging that you already processed, leading you to believe that you are getting repeated data.

(I hope I wrote this clear enough, it is a very confusing bug you got there :)

小巷里的女流氓 2024-09-06 13:01:30

我需要在第二个recv 的长度上添加2,所以我会采用“\r\n”。否则,它看到第一个“\r\n”并认为结尾的行是 buf[0]。

I needed to add 2 to the length of the second recv so I'd take the "\r\n". Otherwise, it sees the first "\r\n" and thinks the line of the end is buf[0].

老旧海报 2024-09-06 13:01:30

嗨,我找到了解决方案:

void receiver(int accepted_client) {
// Ready to receive data from client.
while (true) {
    char buffer[256];
    recv(accepted_client, &buffer, 255, 0);
    int sum = 0;
    for (int i = 0; i < 256; i++) // Check that buffer value is zero or not.
        sum |= buffer[i];

    if (sum != 0) {// If buffer value is not zero then start to print the new received message.
        string string_message(buffer);
        cout << string_message << endl;
    }
    memset(&buffer, 0, 256); // Clear the buffer.
  }
}

Hi i find the solution :

void receiver(int accepted_client) {
// Ready to receive data from client.
while (true) {
    char buffer[256];
    recv(accepted_client, &buffer, 255, 0);
    int sum = 0;
    for (int i = 0; i < 256; i++) // Check that buffer value is zero or not.
        sum |= buffer[i];

    if (sum != 0) {// If buffer value is not zero then start to print the new received message.
        string string_message(buffer);
        cout << string_message << endl;
    }
    memset(&buffer, 0, 256); // Clear the buffer.
  }
}
吃素的狼 2024-09-06 13:01:29

手册指出:

MSG_PEEK
该标志导致接收操作从
接收队列的开头没有
从队列中删除该数据。
因此,后续的接收调用将
返回相同的数据。

所以我认为你得到了正确的行为,但也许期待其他的东西。

The manual states:

MSG_PEEK
This flag causes the receive operation to return data from the
beginning of the receive queue without
removing that data from the queue.
Thus, a subsequent receive call will
return the same data.

So I think you're getting the correct behavior, but perhaps expecting something else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文