粘包和分包

2021-09-24 13:24:57 字數 1696 閱讀 6010

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

頭部長度處理

粘包packagelength:0009123456789packagelength:0008abcdefgh

獲取「packagelength:」這個字串後面4個字元,轉化為數字就是包的長度,根據包的長度獲取後面的內容,第二個內容的長度就是獲取第二個「packagelength:」字串後面的4個字元。

分包packagelength:0009123456

789獲取「packagelength:」這個字串後面4個字元,轉化為數字就是包的長度,如果包結尾還沒有獲取完,那麼就要獲取下乙個包前面的部分內容。

看了前面的例子,比較善於思考的讀者肯定已經想到了一些其他問題,這些問題處理起來方式和上面相似,筆者在此羅列一下,就不重複解釋了,相信聰明的讀者能夠自己解決:

1、粘包和分包問題一起出現

start123456789endstartab

cdefghend

2、頭尾標誌由於分包獲取不完整

start123456789e

nd

Socket粘包分包

粘包和分包問題 1.首先什麼是包 包就是每次伺服器向客戶端傳送的資料每傳送乙個訊息都會被打成乙個包傳送到客戶端。客戶端向伺服器端傳送訊息也是一樣的。2.為什麼會有粘包和分包的問題 是因為sockettcp自身的優化機制所導致的。3.什麼是粘包 粘包就是當伺服器端傳送的資料很小的時候又很頻繁的時候,就...

TCP粘包分包現象

服務端,接收資料,在每次接收到的資料末尾添上乙個 尾 字 客戶端傳送資料,將同樣的資料連續傳送若干次 不是將資料複製若干份一次傳送 using system using system.collections.generic using system.componentmodel using syst...

TCP原理 粘包分包現象

參考 雲棲社群 就是要你懂 tcp 最經典的tcp效能問題 粘包現象產生的原因 由於tcp協議本身的機制 三次握手 客戶端與伺服器會維持乙個連線 channel 資料在連線不斷開的情況下,可以持續不斷地將多個資料報發往伺服器,但是如果傳送的網路資料報太小,那麼他本身會啟用nagle演算法 可配置是否...