2011-06-24 36 views
2

我正在構建一個庫,保持C++中應用程序之間的網絡連接。在一些調試過程中,我發現我從套接字獲得的一些信息似乎不完整。這個信息是完全重要的,因爲如果我用協議緩衝區的庫解碼它,我需要完整的信息。tcp/ip是否傳遞完整的消息?

這種現象不是恆定的。有時我會從套接字獲取所有數據,有時候不會。測試過程如下所示:啓動服務器,多次啓動客戶端。我得到的是函數的輸出,它描述了一些變量的值如何變化。其中之一就是我用來存儲數據的緩衝區的大小。這個大小告訴我緩衝區中有多少數據。客戶發送兩個大小爲3(字節)的消息 - 在這個特定的測試中。我預計緩衝區大小是3的倍數。但是,有時大小是4 !.這意味着程序讀取一條完整的消息和第二條消息的1/3。我不明白爲什麼我總是先收到第一條消息。否則,protobuf會終止程序。

我以爲tcp/ip應該小心我得到完整的消息。我的問題是我不知道大小提前。我希望收到完整的信息,以便我可以解釋它corecty。

回答

9

TCP是基於流的協議,而不是基於消息的協議。 TCP不知道你的信息何時開始或結束,因此沒有保證你會在一次通話中收到完整的信息。也沒有保證,你會得到只有一個完整的消息。您必須緩衝您收到的數據,並將其自動分解成消息。如果您沒有收到完整的信息,請存儲您收到的數據,然後等待其餘的信息到達。

2

允許TCP 片段您的數據分成多個數據報,它們在接收方組裝順序。您保證您的數據最終將以發送的順序到達。但您發送的某些部分數據可能比其他部分早到達。

您所遇到的情況可能是,當您撥打receive時,您發送的部分數據已經到達您的計算機,但其中的一部分仍然通過網絡發送。您將不得不緩衝收到的數據部分,並等待您收到完整的「消息」。處理這種情況的一種方法是在每條消息的開頭髮送一個固定長度的記錄,該消息編碼消息中剩餘字節的長度。例如,您可能會以網絡字節順序發送一個4字節的無符號長整數,然後是多個字節的數據。

相關問題