2014-06-30 24 views
0

我正在用C++編寫客戶端 - 服務器應用程序(TCP協議)。
我有可能客戶端可以從多個服務器接收數據。
爲了解決這個問題,我創建了一個套接字連接列表。在網絡負荷過重時優化接收數據包的過程

在一個循環中,每個插座上,我執行以下操作:

  • 嘗試接收數據在此套接字
  • 把這個緩衝區
  • 過程緩衝區中的數據
  • 清除緩衝區
  • 執行下一個套接字的相同步驟

現在我的設計,最初我爲所有連接創建了一個通用緩衝區。但是我建議,如果網絡負荷很重,可能會發生收到的電報不是完整的電報,它可能是電報的一部分。所以爲了完成一個電報,我將不得不等待下一次迭代才能使用同一個套接字,甚至泡吧/識別電報將是一個複雜的過程。

要處理這種情況,一種解決方案可能是爲每個連接提供專用緩衝區。

任何人都可以提出更優化/更好的解決方案,以避免爲每個連接創建專用緩衝區嗎?

+0

看看Boost Asio http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio.html,所以你不必重新發明輪子。一般來說,如果你需要能夠保存部分數據的實例,你需要有一個緩衝區。還要注意,網絡堆棧會爲你緩衝TCP數據,這取決於你可能足夠好的確切要求。 –

+1

「沒有收到完整的電報」問題不是重負載所特有的。你也會在輕負載上遇到這個問題。 TCP套接字流始終接收部分數據 - 這是TCP的性質(通過分段,分段,在網絡上打嗝等)。無論如何,你總是希望在每個套接字上循環,直到收到完整的消息。 – selbie

+0

@selbie:偉大的一點,同樣的:如果你發送兩個消息,他們可能會收到一個'recv'或'read'調用。最終,TCP是一個帶有流量控制的*字節流*協議,您必須準備好進行阻止和/或部分發送以及部分/合併接收。 –

回答

0

我認爲,如果只想在一次將所有內容全部存儲在內存中時處理整個消息/電報,那麼每個TCP連接的專用接收緩衝區將是唯一的出路。除非你可用的RAM數量非常有限,否則傳入的消息非常大,這應該不成問題。 (如果這是一個問題,請考慮縮小信息的方法;例如,將每條信息分解爲一系列可以串行處理的較小信息)

3

如果您認真對待此問題,每個套接字使用一個線程,每個線程都有自己的緩衝區,可能也會進行處理,或者將其傳遞給特定於連接的處理線程,但如果需要完成,您還可以將所有傳入數據發送到單個「工作」隊列連續出於某種原因。

如果您必須使用單個線程,那麼您必須爲每個連接使用一個緩衝區。 TCP實現了一種流量控制,這意味着發送端可能甚至不允許發送更多的消息,直到接收端消耗足夠的時間。如果您擔心內存使用情況,則可以刪除已完全處理的連接特定緩衝區,並且只有在檢測到不完整的消息時纔會重新創建它們,但通常情況下,最近未訪問的頁面將在緊張內存情況下被換出所以保留內存幾乎沒有什麼壞處 - 只要您的(虛擬)地址空間充足:與重複的動態內存分配和重新分配相關的時間和碎片可能比峯值內存使用率更差。