TCP粘包 拆包

2021-10-22 18:20:41 字數 1030 閱讀 4179

粘包 / 拆包問題是網路比較底層的問題,在資料鏈路層、網路層以及傳輸層都有可能發生。我們日常的網路應用開發大都在傳輸層進行,由於udp有訊息保護邊界,不會發生粘包拆包問題,因此粘包拆包問題只發生在tcp協議中。

假設客戶端向服務端連續傳送了兩個資料報,用packet1和packet2來表示,那麼服務端收到的資料可以分為三種,現列舉如下:

第一種情況,接收端正常收到兩個資料報,即沒有發生拆包和粘包的現象,此種情況不在本文的討論範圍內。

第二種情況,接收端只收到乙個資料報,由於tcp是不會出現丟包的,所以這個資料報中包含了傳送端傳送的兩個資料報的資訊,這種現象即為粘包。這種情況由於接收端不知道這兩個資料報的界限,所以對於接收端來說很難處理。

第三種情況,這種情況有兩種表現形式,如下圖。接收端收到了兩個資料報,但是這兩個資料報要麼是不完整的,要麼就是多出來一塊,這種情況即發生了拆包和粘包。這兩種情況如果不加特殊處理,對於接收端同樣是不好處理的。

發生tcp粘包 / 拆包主要由於以下原因:

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

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

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

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

tcp本身是面向流的,作為網路伺服器,如何這源源不斷湧來的資料流中拆分出或者合併出有意義的資訊呢?通常會有以下常用的方法:

1、包首部。傳送端給每個資料報新增包首部,首部中應該至少包含資料報的長度,這樣接收端在接收到資料後,通過讀取包首部的長度字段,便知道每乙個資料報的實際長度了。

2、固定長度。傳送端將每個資料報封裝為固定長度(不夠的可以通過補0填充),這樣接收端每次從接收緩衝區中讀取固定長度的資料就自然而然的把每個資料報拆分開來。

3、設定邊界。可以在資料報之間設定邊界,如新增特殊符號,這樣,接收端通過這個邊界就可以將不同的資料報拆分開。

TCP粘包 拆包

tcp粘包 拆包 客戶端發服務端傳送了兩個資料報a和b 粘包 服務端一次性接收到了a和b 拆包 服務端第一次接收了a和b的一部分,第二次接收到了b的剩餘部分 粘包 拆包原因 1 應用程式寫入的位元組大小 socket傳送緩衝區大小 2 tcp分段 tcp data部分的大小 mss max segm...

TCP粘包,拆包

粘包 拆包表現形式 現在假設客戶端向服務端連續傳送了兩個資料報,用packet1和packet2來表示,那麼服務端收到的資料可以分為三種,現列舉如下 第一種情況,接收端正常收到兩個資料報,即沒有發生拆包和粘包的現象,此種情況不在本文的討論範圍內。第二種情況,接收端只收到乙個資料報,由於tcp是不會出...

tcp粘包,拆包

客戶端向服務端連續傳送了兩個資料報,接收端正常收到兩個資料報 接收端只收到乙個資料報,由於tcp是不會出現丟包的,所以這乙個資料報中包含了傳送端傳送的兩個資料報的資訊 接收端不知道這兩個資料報的界限,所以對於接收端來說很難處理。接收端收到了兩個資料報,但是這兩個資料報要麼是不完整的,要麼就是多出來一...