2013-05-21 47 views
0

我在我的應用程序中使用winsock來維護客戶端 - 服務器連接,並使用非阻塞套接字來完成此操作。但有時,當我收到FD_READ消息時,看起來recv()不是返回一個,而是兩個數據包。FD_READ:recv()立即返回兩個數據包

我試圖改變數據包的大小,使它們彼此不同,然後將它與數據量recv()正在返回進行比較。我100%確定我會不時收到兩個數據包。我認爲我的ping功能是被責備的。我的應用程序中有一個線程時常發送ping消息。然後另一方回覆另一條消息。不知道這是否是最好的方式,但無論如何,現在並不重要。

我所知道的確有時候這些消息會「混合」,因此recv()一次返回「ping請求」和「ping應答」。它是如何發生的? recv()應該只返回單個呼叫發送的數據量嗎?即使有時客戶端或服務器獲得「ping請求」消息並作出回覆,但在發送其自己的「ping請求」消息時,即使這種不幸的時間可能,也不應該使另一方能夠將一個數據包與另一個數據包相區別並返回每FD_READ消息一個?

回答

1

TCP是數據流,而不是數據包流。 UDP是一個數據包流。正如安東尼所說,如果你使用TCP,你必須處理一部分數據結束和下一部分開始的地方。

+0

所以如果我使用UDP,我不會得到這個問題? – PookyFan

+0

好吧,我明白了。還有一件事:當我從recv()得到這個雙包數據包時,我是否會收到一個或兩個FD_READ消息?我的意思是 - 當我得到FD_READ並調用recv()將兩個數據包都收到緩衝區時,我的應用程序是否會發送另一個FD_READ消息? – PookyFan

+0

劃傷我先前的評論。使用UDP會比較容易,因爲正如標記中所提到的,它確實符合數據包邊界(一次讀取會生成一個數據包)。這對你來說可能更容易使用,但你仍然需要一種方法來區分數據包(大小可能不總是工作)。 – Anthony

1

在上一次調用recv和獲取兩個數據包的時間之間確實收到了兩個數據包。 recv不會一次獲得一個數據包,它會讀取緩衝區中可用的所有數據。這意味着可能有多個可用的數據消息,或者可能只有部分消息可用。 (如果消息足夠大,它將被拆分成多個數據包。)解碼自己的數據是您的工作。一個簡單的方法是通過添加一個包含一些信息的標題來幫助您,如消息標識或預期數據大小的指示。一般來說,使用CRC來驗證數據完整性(並確保您有完整的消息)的腳註也不會造成任何影響。