Socket 粘包和分包問題
概念
Socket通訊時會對傳送的位元組資料進行分包和粘包處理,屬於一種Socket內部的優化機制。
粘包:
當傳送的位元組資料包比較小且頻繁傳送時,Socket內部會將位元組資料進行粘包處理,既將頻繁傳送的小位元組資料打包成 一個整包進行傳送,降低記憶體的消耗。
分包:
當傳送的位元組資料包比較大時,Socket內部會將傳送的位元組資料進行分包處理,降低記憶體和效能的消耗。
例子解釋
當前傳送方傳送了兩個包,兩個包的內容如下:
123456789
ABCDEFGH
我們希望接收方的情況是:收到兩個包,第一個包為:123456789,第二個包為:ABCDEFGH。但是在粘包和分包出現的情況就達不到預期情況。
粘包情況
兩個包在很短的時間間隔內傳送,比如在0.1秒內傳送了這兩個包,如果包長度足夠的話,那麼接收方只會接收到一個包,如下:
123456789ABCDEFGH
分包情況
假設包的長度最長設定為5位元組(較極端的假設,一般長度設定為1000到1500之間),那麼在沒有粘包的情況下,接收方就會收到4個包,如下:
12345
6789
ABCDE
FGH
處理方式
因為存在粘包和分包的情況,所以接收方需要對接收的資料進行一定的處理,主要解決的問題有兩個:
- 在粘包產生時,要可以在同一個包內獲取出多個包的內容。
- 在分包產生時,要保留上一個包的部分內容,與下一個包的部分內容組合。
目前處理方式主要兩種:
一、給資料包的頭尾加上標記。
比如在資料包的頭部加上“START”字串,尾部加上"END"字串,這樣可以解析出START和END之間的字串就是接收方需要接收的內容。(當然真正處理的時候不可能使用START和END這種混效率較高的字串,此處只是個例子)
上邊兩個包的例子就可以如下:
START123456789END
STARTABCDEFGHEND
二、在資料包頭部加上內容的長度
傳送方在傳送的時候就可以在包頭加上包的長度,接收方每次接收的時候都根據頭部的長度去獲取後面的內容。
上邊兩個包的例子就可以如下:
PACKAGELENGTH:0009123456789
PACKAGELENGTH:0008ABCDEFGH
處理例子
頭尾標記處理
粘包
START123456789ENDSTARTABCDEFGHEND
獲取第一個START和第一個END的位置,然後獲取他們之間的內容,第二個包的內容就是獲取第二個START和第二個END的位置。
分包
START1234567
89END
每個包要判斷最後是否是END結尾,如果沒有找到END,那麼就保留上一個包START之後的內容,與下一個包第一個END之前的內容組合。
頭部長度處理
粘包
PACKAGELENGTH:0009123456789PACKAGELENGTH:0008ABCDEFGH
獲取“PACKAGELENGTH:”這個字串後面4個字元,轉化為數字就是包的長度,根據包的長度獲取後面的內容,第二個內容的長度就是獲取第二個“PACKAGELENGTH:”字串後面的4個字元。
分包
PACKAGELENGTH:0009123456
789
獲取“PACKAGELENGTH:”這個字串後面4個字元,轉化為數字就是包的長度,如果包結尾還沒有獲取完,那麼就要獲取下一個包前面的部分內容。
部分細節情況
看了前面的例子,比較善於思考的讀者肯定已經想到了一些其他問題,這些問題處理起來方式和上面相似,筆者在此羅列一下,就不重複解釋了,相信聰明的讀者能夠自己解決:
1、粘包和分包問題一起出現
START123456789ENDSTARTAB
CDEFGHEND
2、頭尾標誌由於分包獲取不完整
START123456789E
ND
相關文章
- socket的半包,粘包與分包的問題
- netty 解決粘包 和 分包的問題Netty
- 25. Socket與粘包問題
- 粘包問題
- TCP粘包拆包問題TCP
- Go TCP 粘包問題GoTCP
- Netty解決粘包和拆包問題的四種方案Netty
- 粘包問題原因和解決方法
- 訊息粘包 和 訊息不完整 問題
- TCP 粘包 - 拆包問題及解決方案TCP
- Netty拾遺(七)——粘包與拆包問題Netty
- TCP協議粘包問題詳解TCP協議
- java nio解決半包 粘包問題Java
- Netty入門系列(2) --使用Netty解決粘包和拆包問題Netty
- 【Socket】解決UDP丟包問題UDP
- 粘包問題、socketserver模組實現併發Server
- Netty 中的粘包和拆包Netty
- Netty2:粘包/拆包問題與使用LineBasedFrameDecoder的解決方案Netty
- 詳說tcp粘包和半包TCP
- TCP 粘包拆包TCP
- socket 斷開和重連問題
- 深入學習Netty(5)——Netty是如何解決TCP粘包/拆包問題的?NettyTCP
- Netty中使用MessagePack時的TCP粘包問題與解決方案NettyTCP
- Netty - 粘包與拆包Netty
- 結合RPC框架通訊談 netty如何解決TCP粘包問題RPC框架NettyTCP
- 粘包/拆包問題一直都存在,只是到TCP就拆不動了。TCP
- swoole 之 tcp 合包分包TCP
- 粘包拆包及解決方案
- TCP的粘包拆包技術TCP
- 每次面試都被問TCP粘包問題,今天終於可以說的清清楚楚了面試TCP
- React Native SDK 升級問題及分包方案React Native
- Netty如何解決粘包拆包?(二)Netty
- 從【零錢兌換】問題看01揹包和完全揹包問題
- 01揹包和完全揹包問題解法模板
- Netty原始碼學習6——netty編碼解碼器&粘包半包問題的解決Netty原始碼
- go語言處理TCP拆包/粘包GoTCP
- Netty Protobuf處理粘包分析Netty
- Netty粘包&半包解決方案Netty