2010-04-28 83 views
2

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

回答

1

manual状态:

MSG_PEEK 此标志将导致接收操作从 开始接收队列的不 返回数据从队列中删除这些数据。 因此,随后的接收呼叫将会返回相同的数据。

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

+0

我有2个呼叫recv的,第二个具有设置为0的标志(不MSG_PEEK)。我正在寻找从第一个recv中得到的“\ r \ n”,然后直到第二个recv的“\ r \ n”。不过,我在写这篇文章时发现了我的问题。我需要添加2到第二个recv的长度,所以我会采取“\ r \ n”。 – anon 2010-04-28 09:31:22

1

你的问题是,当你使用recv和MSG_PEEK时,你给recv缓冲区的整个大小,如果有两行已经存在,比如“HELLO \ r \ nHELLO \ r \ n”它会读取它们进入你的爱好者。然后你用(ptr - buff)调用recv,这会使得recv只读第一个HELLO,进入buf,但是既然你已经把这个信息读入buff,你会处理这两行,但是在你的队列中留下\ r \ nHELLO \ r \ n,因为你没有完全阅读它们。

下一次你会看到它,并有信息挂起,你已经处理,导致你相信你正在获得重复的数据。

(我希望我写这还不够清晰,它是:)

1

我还需要增加2到第二的recv的长度,所以我把“\ r你到了那里一个非常混乱的bug \ N”。否则,它会看到第一个“\ r \ n”,并认为最后一行是buf [0]。

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