1. 程式人生 > >TCP粘包,拆包及解決方法、丟包的原因及解決辦法

TCP粘包,拆包及解決方法、丟包的原因及解決辦法

粘包、拆包發生原因
發生TCP粘包或拆包有很多原因,現列出常見的幾點,可能不全面,歡迎補充,
1、要傳送的資料大於TCP傳送緩衝區剩餘空間大小,將會發生拆包。
2、待發送資料大於MSS(最大報文長度),TCP在傳輸前將進行拆包。
3、要傳送的資料小於TCP傳送緩衝區的大小,TCP將多次寫入緩衝區的資料一次傳送出去,將會發生粘包。
4、接收資料端的應用層沒有及時讀取接收緩衝區中的資料,將發生粘包。
等等。

粘包、拆包解決辦法
通過以上分析,我們清楚了粘包或拆包發生的原因,那麼如何解決這個問題呢?解決問題的關鍵在於如何給每個資料包新增邊界資訊,常用的方法有如下幾個:

1、傳送端給每個資料包新增包首部,首部中應該至少包含資料包的長度,這樣接收端在接收到資料後,通過讀取包首部的長度欄位,便知道每一個數據包的實際長度了。
2、傳送端將每個資料包封裝為固定長度(不夠的可以通過補0填充),這樣接收端每次從接收緩衝區中讀取固定長度的資料就自然而然的把每個資料包拆分開來。
3、可以在資料包之間設定邊界,如新增特殊符號,這樣,接收端通過這個邊界就可以將不同的資料包拆分開。
等等。

測試的時候採用的是一臺機器連續傳送資料來模擬高併發的場景,所以在測試的時候會發現伺服器端收到的資料包的個數經常會小於包的序號,好像發生了丟包。但經過仔細分析可以發現,這種情況是因為TCP傳送快取溢位導致的丟包,也就是這個資料包根本沒有發出來。也就是說,傳送端傳送資料過快,導致接收端快取很快被填滿,這個時候接收端會把通知視窗設定為0從而控制傳送端的流量,這樣新到的資料只能暫存在傳送端的傳送快取中,當傳送快取溢位後,就出現了我上面提到的丟包,這個問題可以通過增大發送端快取來緩解這個問題,