1. 程式人生 > 程式設計 >深入瞭解Netty【八】TCP拆包、粘包和解決方案

深入瞭解Netty【八】TCP拆包、粘包和解決方案


1、TCP協議傳輸過程

TCP協議是面向流的協議,是流式的,沒有業務上的分段,只會根據當前套接字緩衝區的情況進行拆包或者粘包: TCP協議傳輸過程.jpg

傳送端的位元組流都會先傳入緩衝區,再通過網路傳入到接收端的緩衝區中,最終由接收端獲取。

2、TCP粘包和拆包概念

因為TCP會根據緩衝區的實際情況進行包的劃分,在業務上認為,有的包被拆分成多個包進行傳送,也可能多個曉小的包封裝成一個大的包傳送,這就是TCP的粘包或者拆包。

3、TCP粘包和拆包圖解

粘包拆包圖解.png

假設客戶端分別傳送了兩個資料包D1和D2給服務端,由於服務端一次讀取到位元組數是不確定的,故可能存在以下幾種情況: 1. 服務端分兩次讀取到兩個獨立的資料包,分別是D1和D2,沒有粘包和拆包。 2. 服務端一次接收到了兩個資料包,D1和D2粘在一起,發生粘包。 3. 服務端分兩次讀取到資料包,第一次讀取到了完整的D1包和D2包的部分內容,第二次讀取到了D2包的剩餘內容,發生拆包。 4. 服務端分兩次讀取到資料包,第一次讀取到部分D1包,第二次讀取到剩餘的D1包和全部的D2包。

當TCP快取再小一點的話,會把D1和D2分別拆成多個包傳送。

4、TCP粘包和拆包解決策略

因為TCP只負責資料傳送,並不處理業務上的資料,所以只能在上層應用協議棧解決,目前的解決方案歸納: 1. 訊息定長,每個報文的大小固定,如果資料不夠,空位補空格。 2. 在包的尾部加回車換行符標識。 3. 將訊息分為訊息頭與訊息體,訊息頭中包含訊息總長度。 4. 設計更復雜的協議。

5、Netty中的解決辦法

Netty提供了多種預設的編碼器解決粘包和拆包: Netty解決方案.png

5.1、LineBasedFrameDecoder

基於回車換行符的解碼器,當遇到