2010-12-11 60 views
2

我遇到了一個有趣的C套接字問題。C套接字 - 一次隨機接收多個字符串

我正在接收傳入的字符串,並注意到我會隨機接收3個字符串,同時爲第2〜4個字符串。

例如,我收到以下傳入字符串。

1~message~i love you\r\n 
2~message~do you love me?\r\n 
3~message~when are we going to meet again?\r\n 
4~message~How about now?\r\n 
5~message~Oh! I'm pregnant!\r\n 

我添加了一個計數器來跟蹤所接收的消息的數量,並注意到計數器有時不計算所述第一3個字符串。例如

1~message~i love you\r\n 
->Line 1 received 
2~message~do you love me?\r\n 
3~message~when are we going to meet again?\r\n 
4~message~How about now?\r\n 
->Line 2 received 
5~message~Oh! I'm pregnant!\r\n 
->Line 3 received 

以下是我對打印行數

int lineNo = 1; 
while ((recvBytes = recv(clntSockfd, buffer, sizeof(buffer), 0)) > 0) { 
    printf("%s", buffer); 
    memset(&buffer, 0, sizeof(buffer)); 
    printf("Line %d received\n", lineNo++); 
} 

我不知道爲什麼會這樣,因爲當我用Java NIO編碼這個問題沒有出現代碼。

任何想法,鄉親?

回答

0

你使用什麼連接類型?

UDP在大多數情況下是不可靠的。

就可靠性而言,TCP比UDP好得多。

+0

嘿Neilvert,我正在使用TCP。 – Poliquin 2010-12-11 15:36:42

1

您沒有閱讀到行尾。 buffer可以包含多行

8

假設您使用TCP,將recv()調用與您的案例中的「消息」(或「行」)相關聯是有缺陷的。 TCP在概念上是一個字節流。發送操作系統可以將多個send()調用分組爲單個IP數據包,接收操作系統可以自由報告多個傳入數據包爲單個recv()調用(假設緩衝區足夠大)。它甚至可以選擇通過recv呼叫拆分傳入數據包。

所以,你真的需要在數據本身,例如消息結構。通過掃描接收到的數據中的換行符。

Java中沒有發生這種情況是純粹的運氣。

+0

在回送過程中,您傾向於獲取發送大小的數據包。然而,在真實網絡中,這很難避免合併數據包。如果發送數據包的間隔時間大約爲100 ms,則通常會按照它們發送的大小獲取數據包,但不應該依賴此行爲。 – 2010-12-11 11:00:46

+0

嘿傢伙,謝謝你的擡頭。我想我會像馬丁建議的那樣掃描換行符。我在晚餐時一直在想它。現在我回來了,可能會更多一點。看着strtok()和strtok_r()。 strtok_r()看起來更好,因爲文檔說它對線程有好處。此外,我打算將字符串「1〜信息〜我愛你\ r \ n」分解爲「1」「信息」「我愛你」的每個標記。 – Poliquin 2010-12-11 15:40:14