Tcp程式設計常見問題及解決方法

Tcp程式設計常見問題及解決方法

問題1、粘包問題

解決方法一:TCP提供了強制資料立即傳送的操作指令push,TCP軟體收到該操作指令後,就立即將本段資料傳送出去,而不必等待發送緩衝區滿;

解決方法二:傳送固定長度的訊息

解決方法三:把訊息的尺寸與訊息一塊傳送

解決方法四:雙方約定每次傳送的大小

解決方法五:雙方約定使用特殊標記來區分訊息間隔

解決方法六:標準協議按協議規則處理,如Sip協議

問題2、字串編碼問題

將中文字串用utf8編碼格式轉換為位元組陣列傳送時,一箇中文字元可能會佔用2~4個位元組(假設為3個位元組),這3個位元組可能分3次接收,接收端每次接收完後用utf8編碼格式轉換為字串,就會出現亂碼,並導致接收長度計算錯誤的情況。

解決方法一:以位元組數做為訊息長度的計算單位,而不是字元個數。

解決方法二:傳送方和接收方都採用unicode編碼格式。

問題3、長連線的保活問題

標準TCP層協議裡把對方超時設為2小時,若伺服器端超過了2小時還沒收到客戶的資訊,它就傳送探測報文段,若傳送了10個探測報文段(每一個相隔75S)還沒有收到響應,就假定客戶出了故障,並終止這個連線。因此應對tcp長連線進行保活。

以下是非同步通訊時會遇到的問題:

問題4、緩衝區髒資料問題

同步傳送的複製,是直接複製資料到基礎系統緩衝區,複製完成後返回;

非同步傳送訊息的複製,是將Socket自帶的Buffer空間內的所有資料,複製到基礎系統傳送緩衝區,並立即返回;

因此非同步傳送時緩衝區設定不好會導致接收到髒資料的問題,如下所示:

第一次傳送資料:1234567890

第一次接受資料:1234567890

第二次傳送資料:abc

第二次接受資料:abc4567890

請參考:http://www。cnblogs。com/tianzhiliang/archive/2010/09/08/1821623。html

解決方法一:將緩衝區的大小設定為實際傳送資料的大小。

問題5、記憶體碎片問題

頻繁的申請緩衝區會導致記憶體碎片的問題。

解決方法一:使用物件池和記憶體池。

請參考MSDN:http://msdn。microsoft。com/zh-cn/library/bb517542(v=vs。100)。aspx

http://msdn。microsoft。com/zh-cn/library/system。net。sockets。socketasynceventargs。socketasynceventargs(v=vs。100)。aspx

問題6、亂序問題

多個執行緒使用非同步通訊方式向同一個接收端(socket)同時傳送資料,會導致接收端接收的資料混亂。如下所示:

執行緒1第一次傳送:123456789,假設未傳送完,只發送了123

執行緒2第一次傳送:abcdefgh,假設未傳送完,只發送了abc

執行緒1第二次傳送:456789,傳送完成

執行緒2第二次傳送:defgh,傳送完成

接收端最終接收的資料為:123abc456789defgh。

解決方法一:一個連線的傳送端執行緒排隊傳送資料。

感謝原作者

https://www。cnblogs。com/wenjingu/p/3809778。html