1. 程式人生 > >netty學習筆記一:TCP粘包拆包

netty學習筆記一:TCP粘包拆包

min -s 原因 兩個 image 分享 技術 ima 選項

什麽是TCP拆包粘包

假設客戶端發送了2條消息M1,M2。可能會出現以下幾種情況。

1、服務端正常接收到M1,M2這兩條消息。

技術分享圖片

2、服務端一次接收到了2個數據包,M1和M2粘合在一起,這時候就被稱為TCP粘包。

技術分享圖片

3、服務端分兩次讀取到了兩個數據包,第一次讀取到M1包整包和M2包部分內容M2_1,第二次讀取到了M2剩余的內容M2_2,這時候被稱為TCP拆包。

技術分享圖片

4、服務端分兩次讀取到了兩個數據包,第一次讀取到M1包的部分內容M1_1,第二次讀取到了M1剩余的內容M1_2和M2整包,這時候也是發生了TCP拆包。

技術分享圖片

5、當服務端TCP接收滑窗非常小,或者M1、M2數據包比較大時,服務端需要將M1,M2進行多次拆包才能接收完全,這時候也是發生了TCP拆包。

技術分享圖片

同時,我們需要明確的是,其實在TCP層面上它是沒有拆包粘包概念的。因為TCP只是負責傳輸上層協議所提供的數據,它本身並不知道這些數據的關系,只是像流一樣將這些數據傳輸過去。因此,這個拆包粘包概念更準確來說是相對於應用層數據劃分的。

拆包粘包產生原因

粘包可能的產生原因

技術分享圖片

  1、原本沒有粘包進行TCP傳輸的數據包,在read操作調用不及時去讀取緩沖區數據的情況下,很可能會發生粘包;

  2、應用程序寫入數據大小小於緩沖區大小,網卡會將應用多次寫入的數據發送到網絡上,這將會發生粘包。

拆包可能的產生原因

技術分享圖片

1、應用程序寫入的數據比緩沖區還大時,數據不能一次性發送,將發生拆包。

技術分享圖片

2、TCP進行分段時數據大小大於MSS大小的時候將發生拆包。

3、以太網幀的payload數據大於MTU大小時發生拆包。

註:MTU和MSS的概念如下。

MTU:代表TCP/IP協議傳輸數據報時的最大傳輸單元。以太網協議規定最大幀長度是1500Byte(不包括報文頭部)。

MSS: MSS是TCP專屬概念,TCP在三次握手建立連接過程中,會在SYN報文中使用MSS(Maximum Segment Size)選項功能,協商交互雙方能夠接收的最大段長MSS值。其標識TCP能夠承載的最大的應用數據段長度。

MSS=MTU-20字節TCP報頭-20字節IP報頭。在IPv4網絡中,一般情況下,MSS=1460=1500-20-20。 在IPv6網絡中,一般情況下,MSS=1440=1500-20-40。

常見解決策略

1、消息定長。例如每個報文的大小固定為200字節,不夠則空格補齊;

2、在包尾增加回車換行符進行分割,如FTP協議;

3、將消息分成消息頭和消息體,消息頭中包含表示消息()總長度的字段。如下示例,length字段代表本條消息的長度大小。

+————+—————————+

| Length | Actual Content |

| 0x000C | "HELLO, WORLD" |

+————+—————+———-+

Netty常見解決類

1、LineBasedFrameDecoder:基於行來進行消息粘包拆包處理的。

2、DelimiterBaseFrameDecoder:基於分隔符做結束標誌進行粘包拆包處理的,對於使用"\n","\r\n"做分隔符內部會調用LineBasedFrameDecoder來做統一的行分割。

3、FixedLengthFrameDecoder:基於固定長度消息進行粘包拆包處理的。

4、LengthFieldBasedFrameDecoder:基於消息頭指定消息長度進行粘包拆包處理的。

netty學習筆記一:TCP粘包拆包