產生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...