recv返回旧数据

recv返回旧数据,c,sockets,buffer,recv,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

这个循环应该逐行从套接字获取数据并将其放入缓冲区。出于某种原因,当没有新数据要返回时,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
}
各国:

味精聚醚醚酮 此标志导致接收操作从 接收队列的开头不带 正在从队列中删除该数据。 因此,随后的接收呼叫将 返回相同的数据


因此,我认为您得到了正确的行为,但可能期待着其他东西。

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

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

下一次你会偷看它,发现你已经处理过的信息挂在那里,让你相信你得到的是重复的数据。


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

我需要在第二个recv的长度上加上2,所以我将使用“\r\n”。否则,它会看到第一个“\r\n”,并认为末尾的行是buf[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.
  }
}
void接收方(int接受的\u客户端){
//准备从客户端接收数据。
while(true){
字符缓冲区[256];
recv(已接受的客户端和缓冲区,255,0);
整数和=0;
对于(int i=0;i<256;i++)//检查缓冲区值是否为零。
总和|=缓冲区[i];
如果(sum!=0){//如果缓冲区值不为零,则开始打印新收到的消息。
字符串消息(缓冲区);

我可以对recv进行两次调用,第二次调用的标志设置为0(不是MSG_PEEK)。我在从第一次recv获得的内容中查找“\r\n”,然后只在第二次recv上取“\r\n”。不过,我在编写时发现了问题。我需要在第二次recv的长度中添加2,以便取“\r\n”。