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