TCP粘包原因及解決辦法

2021-10-16 09:27:06 字數 2405 閱讀 8068

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

比如說:傳送方傳送了兩個資料,接收方一次收了乙個半資料(接收方可能不清楚乙個包有多大)

ip報文:

tcp報文:

udp報文:

ip和udp都有16位的長度字段,理論上ip和udp報文的最大負載長度應該為2^16,64kb,而tcp沒有長度字段,理論上應該和ip一樣。

但是存在其他限制

網路層限制:mtu(maximum transmission unit,最大傳輸單元),這限制了ip報文長度,ip報文長度大於mtu,就需要分片。通常設為1500位元組。

傳輸層限制:tcp協議中有個mss(最大報文長度),tcp通常將資料分成長度為mss的若干塊。通常為mtu(1500)-ip資料報包頭(20)-tcp資料段的包頭(20)=1460位元組。

所以tcp一次傳輸資料應該最大有1460位元組。

出現粘包現象的原因是多方面的,它既可能由傳送方造成,也可能由接收方造成。

傳送方引起的粘包是由tcp協議本身造成的:

接收方引起的粘包是由於接收方使用者程序不及時接收資料,從而導致粘包現象。這是因為接收方先把收到的資料放在系統接收緩衝區,使用者程序從該緩衝區取資料,若下一包資料到達時前一包資料尚未被使用者程序取走,則下一包資料放到系統接收緩衝區時就接到前一包資料之後,而使用者程序根據預先設定的緩衝區大小從系統接收緩衝區取資料,這樣就一次取到了多包資料。

在**中常見體現:

要傳送的資料大於tcp傳送緩衝區剩餘空間大小,將會發生拆包。

要傳送的資料大於mss,tcp在傳輸前將進行拆包。

要傳送的資料小於tcp傳送緩衝區的大小,tcp將多次寫入緩衝區的資料一次傳送出去,將會發生粘包。

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

等等。

當時短連線的情況下,不用考慮粘包的情況

如果傳送資料無結構,如檔案傳輸,這樣傳送方只管傳送,接收方只管接收儲存就ok,也不用考慮粘包

如果雙方建立長連線,需要在連線後一段時間內傳送不同結構資料

在網課學習中看到的指定資料長度的解決方法,主要思路:

我們在資料結構中有個成員代表了長度(訊息頭),我們準備乙個足夠大的訊息緩衝區(程式中是1024000個位元組),迴圈使用socket中的recv每次讀取最多102400個位元組,然後把迴圈接收的訊息拼接到訊息緩衝區中,直到接收到的訊息大於訊息頭指示的長度,則接收到了乙個完整的訊息(所以我們的訊息緩衝區要比完整的訊息還要大才行),進行訊息處理。

主要**:

// 緩衝區最小單元大小

#ifndef

recv_buff_szie

#define

recv_buff_szie

102400

#endif

// !recv_buff_szie

// 第二緩衝區 訊息緩衝區

char _szmsgbuf[recv_buff_szie *10]

=;// 訊息緩衝區的資料尾部位置

int _lastpos =0;

// 接收緩衝區

char _szrecv[recv_buff_szie]=;

// 接收資料 處理粘包 拆分包

intrecvdata

(socket csock)

// 將收取到的資料拷貝到訊息緩衝區

memcpy

(_szmsgbuf+_lastpos, _szrecv, nlen)

;// 訊息緩衝區的資料尾部位置後移

_lastpos += nlen;

// 判斷訊息緩衝區的資料長度大於訊息頭dataheader長度

while

(_lastpos >=

sizeof

(dataheader)

)else

}return0;

}

TCP的粘包和拆包問題及解決辦法(C )

本文參考 如果客戶端連續不斷的向服務端傳送資料報時,服務端接收的資料會出現兩個資料報粘在一起的情況,這就是tcp協議中經常會遇到的粘包以及拆包的問題。我們都知道tcp屬於傳輸層的協議,傳輸層除了有tcp協議外還有udp協議。tcp tcp是基於位元組流的,雖然應用層和tcp傳輸層之間的資料互動是大小...

TCP的粘包和拆包問題及解決辦法(C )

因此,解決問題的關鍵在於如何給每個資料報新增邊界資訊,基本上有以下三種常見解決辦法 使用第一種方法,寫乙個構造包的類,包括 包頭 資料長度 和包尾 資料 class encodetool 承接上面encodetool類 public static byte decodepacket ref list...

粘包現象與解決辦法

一 什麼是粘包現象 須知 只有tcp有粘包現象,udp永遠不會粘包 粘包不一定會發生,如果發生了 1.可能是在客戶端已經粘了,2.客戶端沒有粘,可能是在服務端粘了 粘包現象 tcp粘包是指傳送方傳送的若干包資料到接收方接收時粘成一包,從接收緩衝區看,後一包資料的頭緊接著前一包資料的尾。成因 所謂粘包...