TCP 粘包拆包

WindWant發表於2020-06-20

一、什麼是粘包拆包?

粘包拆包是TCP協議傳輸中一種現象概念。TCP是傳輸層協議,他傳輸的是“流”式資料,TCP並不知道傳輸是哪種業務資料,或者說,並不關心。它只是根據緩衝區狀況將資料進行包劃分,然後進行傳輸。

在這個前提下,就有可能發生發生同一個業務資料被分割程多個資料包,或者多個業務資料被打包到同一個資料包進行傳送。但是對於業務資料接收方,則必須擁有能夠重新拆解或者組裝完整業務資料的能力。這個現象,我們稱之為TCP粘包拆包。

 

如上圖,三個業務資料A、B、C被打包成一個資料包進行傳輸;D被分割為連個資料包進行傳輸。

所以綜上,影響粘包拆包發生的原因:

1、業務資料的大小<>TCP 套接字緩衝區大小

如果需要寫入的應用資料大於當前設定的TCP套接字緩衝區,則需要對應用資料進行分次寫入。

SO_SNDBUF:傳送緩衝區大小。

SO_RCVBUF:接收緩衝區大小。

應用首先將資料寫入TCP套接字緩衝區,然後等待傳送。預設情況下,多數作業系統支援動態調節SO_SNDBUF大小以進行自適應,但是如果有主動設定,則自動調節會失效。

2、MSS大小傳輸線制

標識TCP傳往另一段的最大資料長度,建立連線時,雙發通告自己允許的MSS(只能出現在SYN報文中)。

3、MTU大小限制

網路中主機之間的MTU不是一個常數,取決於所選擇的路由,而且路徑不一定對稱(A到B的選路,B到A的選路).

因為每一次傳送報文都會包含IP及TCP首部,所以,傳送的報文段越大,效率越高,但是以不發生報文分段及雙方都接受為基礎。否則以較小的MTU傳送。

關於MTU MSS相關知識可以參照:MTU(Maximum transmission unit) 最大傳輸單元

二、怎麼處理粘包拆包?

傳輸層是業務無感知的,因此粘包拆包只能由業務層處理。通過指定收發兩端共同的約定規約,傳送方按照特定的規則組裝資料,接收方按照同樣的規則拆解資料。

這個共同的約定規約,我們通常稱之為應用層協議;傳送方組裝資料的過程稱之為編碼;接收方拆解資料的過程稱之為解碼。

常見的協議處理有如下:

1、固定長度訊息

在預知最大報文不超特定長度的情況下,可以規定報文大小固定,業務資料不足則以特定的空間佔位。

2、特定分隔符分割訊息

每條訊息尾部加特定分割符進行訊息分割。

3、訊息頭+訊息體

每一條訊息包含一個訊息頭和一個訊息體,訊息頭使用固定長度佔位,內部寫入當前訊息訊息體的資料長度。接收方首先讀取訊息頭資料,然後根據指明的訊息長度進行訊息體的讀取。

應用協議沒有統一的規則限制,如上,我們只是簡要說明可能使用的應用協議形式,實際應用中,也會根據特定的場景需求進行定向的優化。

 

相關文章