2010-04-28 87 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. 
    } 
}