recv返回旧数据

时间:2010-04-28 09:11:29

标签: c sockets buffer recv

这个循环应该逐行从套接字中获取数据并将其放入缓冲区。出于某种原因,当没有要返回的新数据时,recv返回它获得的最后几行。我能够通过评论第一个recv来阻止这个bug,但后来我不知道下一行会有多长。我知道这不是

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
}

4 个答案:

答案 0 :(得分:1)

manual州:

  

MSG_PEEK       此标志使接收操作从中返回数据   没有接收队列的开头   从队列中删除该数据。   因此,随后的接收呼叫将   返回相同的数据。

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

答案 1 :(得分:1)

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

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

下次您将查看它并暂停已经处理的信息,这会让您相信您正在获取重复数据。

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

您好我找到了解决方案:

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.
  }
}