TCP粘包概念 產生原因及解決方法

2021-10-07 02:38:22 字數 1716 閱讀 1867

所謂粘包問題主要還是因為接收方不知道訊息之間的界限,不知道一次性提取多少位元組的資料所造成的。

• 傳送端原因:由於tcp協議本身的機制(面向連線的可靠地協議-三次握手機制)客戶端與伺服器會維持乙個連線(channel),資料在連線不斷開的情況下,可以持續不斷地將多個資料報發往伺服器,但是如果傳送的網路資料報太小,那麼他本身會啟用nagle演算法(可配置是否啟用)對較小的資料報進行合併(基於此,tcp的網路延遲要udp的高些)然後再傳送(超時或者包大小足夠)。那麼這樣的話,伺服器在接收到訊息(資料流)的時候就無法區分哪些資料報是客戶端自己分開傳送的,這樣產生了粘包.

• 接收端原因:伺服器在接收到資料庫後,放到緩衝區中,如果訊息沒有被及時從快取區取走,下次在取資料的時候可能就會出現一次取出多個資料報的情況,造成粘包現象。

對於傳送方造成的粘包現象,我們可以通過關閉nagle演算法來解決,使用tcp_nodelay選項來關閉nagle演算法。

tcp_nodelay nagle詳解

遺憾的是tcp並沒有處理接收方粘包現象的機制,我們只能在應用層進行處理。

應用層處理

應用層的處理簡單易行!並且不僅可以解決接收方造成的粘包問題,還能解決傳送方造成的粘包問題。

解決方法就是迴圈處理:應用程式在處理從快取讀來的分組時,讀完一條資料時,就應該迴圈讀下一條資料,直到所有的資料都被處理;但是如何判斷每條資料的長度呢?

1)格式化資料:每條資料有固定的格式(開始符、結束符),這種方法簡單易行,但選擇開始符和結束符的時候一定要注意每條資料的內部一定不能出現開始符或結束符;

注意控制符的轉義

2)傳送長度:傳送每條資料的時候,將資料的長度一併傳送,比如可以選擇每條資料的前4位是資料的長度,應用層處理時可以根據長度來判斷每條資料的開始和結束。

參考tlv 格式及編譯碼

tlv一種可變格式,tlv的意思就是:type型別, lenght長度,value值;

type和length的長度固定,一般那是2、4個位元組;

value的長度有length指定;

tlvtag,lengthvalue的縮寫.乙個基本的資料元就包括上面三個域.tag唯一標識該資料元,lengthvalue域的長度. value就是資料本身了. 舉個例子, 下面是乙個tlv格式的aid(應用識別符號)位元組串」9f06 07a0000000031010」, 其中9f06tag,07是長度,a0000000031010就是aid本身的值了.

其實該命題是個偽問題,tcp是面向位元組流的,不存在包這個概念,該問題實際上是tcp資料的無邊界性,是乙個應用層的問題

這裡提供乙個非常不錯的解釋:

怎麼解決tcp網路傳輸「粘包」問題?

順便再看看知乎的討論 蠻有意思的的一場辯論

[1]

[2]

[3]

[4]

[5]

TCP粘包原因及解決辦法

粘包 多個資料報被連續儲存於連續的快取中,在對資料報進行讀取時由於無法確定發生方的傳送邊界,而採用某一估測值大小來進行資料讀出,若雙方的size不一致時就會使指傳送方傳送的若干包資料到接收方接收時粘成一包,從接收緩衝區看,後一包資料的頭緊接著前一包資料的尾。比如說 傳送方傳送了兩個資料,接收方一次收...

TCP 粘包 拆包的原因及解決方法

在平時客戶端socket開發中,如果客戶端連續不斷的向服務端傳送資料報時,服務端接收的資料會出現兩個資料報粘在一起的情況,這就是tcp協議中經常會遇到的粘包以及拆包的問題。我們都知道tcp屬於傳輸層的協議,傳輸層除了有tcp協議外還有udp協議。那麼udp是否會發生粘包或拆包的現象呢?答案是不會。u...

TCP粘包和拆包的定義,產生的原因以及解決方案

tcp粘包 指傳送方傳送的若干資料報在接收方接收時粘成一團,從接收緩衝區看,後一包資料的頭緊接著前一包資料的尾 產生的原因 1.傳送方的原因 tcp預設使用nagle演算法,而nagle演算法主要做兩件事情 只有上乙個分組得到確認,才傳送下乙個分組,收集多個小分組,在乙個確認到來時一起傳送,nagl...