關於socket粘包、拆包的解決方法總結

在平時客戶端socket開發中,若是客戶端接二連三的向服務端發送數據包時,服務端接收的數據會出現兩個數據包粘在一塊兒的狀況,這就是TCP協議中常常會遇到的粘包以及拆包的問題。socket

咱們都知道TCP屬於傳輸層的協議,傳輸層除了有TCP協議外還有UDP協議。那麼UDP是否會發生粘包或拆包的現象呢?答案是不會。UDP是基於報文發送的,從UDP的幀結構能夠看出,在UDP首部採用了16bit來指示UDP數據報文的長度,所以在應用層能很好的將不一樣的數據報文區分開,從而避免粘包和拆包的問題。而TCP是基於字節流的,雖然應用層和TCP傳輸層之間的數據交互是大小不等的數據塊,可是TCP把這些數據塊僅僅當作一連串無結構的字節流,沒有邊界;另外從TCP的幀結構也能夠看出,在TCP的首部沒有表示數據長度的字段,基於上面兩點,在使用TCP傳輸數據時,纔有粘包或者拆包現象發生的可能。開發

粘包、拆包表現形式it

如今假設客戶端向服務端連續發送了兩個數據包,用packet1和packet2來表示,那麼服務端收到的數據能夠分爲三種,現列舉以下:方法

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

第二種狀況,接收端只收到一個數據包,因爲TCP是不會出現丟包的,因此這一個數據包中包含了發送端發送的兩個數據包的信息,這種現象即爲粘包。這種狀況因爲接收端不知道這兩個數據包的界限,因此對於接收端來講很難處理。數據

第三種狀況,這種狀況有兩種表現形式,以下圖。接收端收到了兩個數據包,可是這兩個數據包要麼是不完整的,要麼就是多出來一塊,這種狀況即發生了拆包和粘包。這兩種狀況若是不加特殊處理,對於接收端一樣是很差處理的。客戶端

 

粘包、拆包發生緣由協議

發生TCP粘包或拆包有不少緣由,現列出常見的幾點,可能不全面,歡迎補充,img

一、要發送的數據大於TCP發送緩衝區剩餘空間大小,將會發生拆包。服務端

二、待發送數據大於MSS(最大報文長度),TCP在傳輸前將進行拆包。

三、要發送的數據小於TCP發送緩衝區的大小,TCP將屢次寫入緩衝區的數據一次發送出去,將會發生粘包。

四、接收數據端的應用層沒有及時讀取接收緩衝區中的數據,將發生粘包。

等等。

粘包、拆包解決辦法

經過以上分析,咱們清楚了粘包或拆包發生的緣由,那麼如何解決這個問題呢?解決問題的關鍵在於如何給每一個數據包添加邊界信息,經常使用的方法有以下幾個:

一、發送端給每一個數據包添加包首部,首部中應該至少包含數據包的長度,這樣接收端在接收到數據後,經過讀取包首部的長度字段,便知道每個數據包的實際長度了。

二、發送端將每一個數據包封裝爲固定長度(不夠的能夠經過補0填充),這樣接收端每次從接收緩衝區中讀取固定長度的數據就天然而然的把每一個數據包拆分開來。

三、能夠在數據包之間設置邊界,如添加特殊符號,這樣,接收端經過這個邊界就能夠將不一樣的數據包拆分開。

等等。

相關文章
相關標籤/搜索