tcp粘包和拆包的處理方案

2021-09-19 13:22:09 字數 1860 閱讀 4134

產生tcp粘包和拆包的原因

我們知道tcp是以流動的方式傳輸資料,傳輸的最小單位為乙個報文段(segment)。tcp header中有個options標識位,常見的標識為mss(maximum segment size最大訊息長度)指的是,連線層每次傳輸的資料有個最大限制mtu(maximum transmission unit),一般是1500位元,超過這個量要分成多個報文段,mss則是這個最大限制減去tcp的header,光是要傳輸的資料的大小,一般為1460位元。換算成位元組,也就是180多位元組。

mss = mtu - header 

tcp為提高效能,傳送端會將需要傳送的資料傳送到緩衝區,等待緩衝區滿了之後,再將緩衝中的資料傳送到接收方。同理,接收方也有緩衝區這樣的機制,來接收資料。

發生tcp粘包、拆包主要是由於下面一些原因:

應用程式寫入的資料大於套接字緩衝區大小,這將會發生拆包。

應用程式寫入資料小於套接字緩衝區大小,網絡卡將應用多次寫入的資料傳送到網路上,這將會發生粘包。

進行mss(最大報文長度)大小的tcp分段,當tcp報文長度-tcp頭部長度》mss的時候將發生拆包。

接收方法不及時讀取套接字緩衝區資料,這將發生粘包。

如何解決拆包粘包

既然知道了tcp是無界的資料流,且協議本身無法避免粘包,拆包的發生,那我們只能在應用層資料協議上,加以控制。通常在制定傳輸資料時,可以使用如下方法:

1、使用帶訊息頭的協議、訊息頭儲存訊息開始標識及訊息長度資訊,服務端獲取訊息頭的時候解析出訊息長度,然後向後讀取該長度的內容。

2、設定定長訊息,服務端每次讀取既定長度的內容作為一條完整訊息。

3、設定訊息邊界,服務端從網路流中按訊息編輯分離出訊息內容。

問題:tcp是以段為單位進行資料報的傳送的。

(1)在建立tcp連線的同時,也可以確定傳送資料報的單位,稱之為「最大訊息長度」:mss。最理想的情況是,最大訊息長度mss正好是ip層中不被分片處理的最大資料長度。

(2)tcp在傳送大量資料的時候,是以「段=mss的大小」將資料進行分割傳送的,進行重發時也是以mss為單位的。

(3)最大訊息長度——mss是在三次握手的時候,在兩端主機之間被計算得出的。兩端主機在發出「建立tcp連線請求的syn包」時,會在syn包的tcp首部中寫入mss選項,告訴對方自己所能夠適應的mss的大小,然後傳送端主機會在兩者之間選擇乙個較小的mss值投入使用。

tcp為什麼引入接受快取這個資料結構?

如果沒有接受快取的話,或者說只有乙個快取的話,為了保證接受的資料是按順序傳輸的,所以如果位於x序號之後的序號分組先到達目的主機的運輸層的話必然丟棄,這樣的話將在重傳上花費很大的開銷,所以一般如果有過大的序號達到接收端,那麼會按照序號快取起來等待之前的序號分許到達,然後一併交付到應用程序。

tcp 粘包/拆包的原因及解決方法

tcp是以流的方式來處理資料,乙個完整的包可能會被tcp拆分成多個包進行傳送,也可能把小的封裝成乙個大的資料報傳送。

tcp粘包/分包的原因:

應用程式寫入的位元組大小大於套接字傳送緩衝區的大小,會發生拆包現象,而應用程式寫入資料小於套接字緩衝區大小,網絡卡將應用多次寫入的資料傳送到網路上,這將會發生粘包現象;

進行mss大小的tcp分段,當tcp報文長度-tcp頭部長度》mss的時候將發生拆包

乙太網幀的payload(淨荷)大於mtu(1500位元組)進行ip分片。

解決方法

訊息定長:fixedlengthframedecoder類

包尾增加特殊字元分割:行分隔符類:linebasedframedecoder或自定義分隔符類 :delimiterbasedframedecoder

將訊息分為訊息頭和訊息體:lengthfieldbasedframedecoder類。分為有頭部的拆包與粘包、長度欄位在前且有頭部的拆包與粘包、多擴充套件頭部的拆包與粘包。

tcp粘包和拆包的處理方案

隨著智慧型硬體越來越流行,很多後端開發人員都有可能接觸到socket程式設計。而很多情況下,伺服器與端上需要保證資料的有序,穩定到達,自然而然就會選擇基於tcp ip協議的socekt開發。開發過程中,經常會遇到tcp粘包,拆包的問題,本文將從產生原因,和解決方案以及workerman是如何處理粘包...

tcp粘包和拆包的處理方案

隨著智慧型硬體越來越流行,很多後端開發人員都有可能接觸到socket程式設計。而很多情況下,伺服器與端上需要保證資料的有序,穩定到達,自然而然就會選擇基於tcp ip協議的socekt開發。開發過程中,經常會遇到tcp粘包,拆包的問題,本文將從產生原因,和解決方案以及workerman是如何處理粘包...

TCP粘包的拆包處理

因為tcp是流式處理的,所以包沒有邊界,必須設計乙個包頭,裡面表示包的長度 一般用位元組表示 根據這個來逐個拆包。如果對於傳送 接收頻率不高的話,一般也就不做拆包處理了,因為不大可能有粘包現象。以下是粘包和拆包的分析 用qt的tcpsocket讀出的資料來拆 1 m imp m thread boo...