Netty解決半包(TCP粘包/拆包導致)讀寫問題

工程師WWW發表於2015-05-12

TCP粘包/拆包

TCP是個"流"協議,所謂流,就是沒有界限沒有分割的一串資料。TCP會根據緩衝區的實際情況進行包劃分,一個完整的包可能會拆分成多個包進行傳送,也用可能把多個小包封裝成一個大的資料包傳送。這就是TCP粘包/拆包。


TCP粘包/拆包問題說明

客戶端要給服務端傳送資料,假如為兩個資料包。

可能的情況如下:


問題產生的原因:

1-應用程式write寫入的位元組大小 大於 套接字傳送緩衝區大小

2-進行MSS大小的TCP分段

3-乙太網幀的payload大於MTU進行IP分片


TCP粘包/拆包解決辦法

1-定長訊息,例如每個報文長度固定,不夠補空格

2-使用回車換行符分割,在包尾加上分割符,例如Ftp協議

3-訊息分割,頭為長度(訊息總長度或訊息體長度),通常頭用一個int32表示

4-複雜的應用層協議


Netty對於讀寫半包的的處理

提供多種解碼器用於處理半包,如 LineBasedFrameDecoder、DelimiterBasedFrameDecoder、FixedLengthFrameDecoder、ProtobufVarint32FrameDecoder、ByteToMessageDecoder以及LengthFileldBasedFrameDecoder等等。

下面的例子為 我在 ProtoBuf中的使用

?
1
2
3
4
5
6
7
8
//decoder
//1-讀半包的解碼器
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(10240404)); 
//2-進行訊息解碼
ch.pipeline().addLast(new ProtobufDecoder(BoxAuthReqProto.AuthRequest.getDefaultInstance()));
//encoder                  
ch.pipeline().addLast(new LengthFieldPrepender(4));
ch.pipeline().addLast(new ProtobufEncoder());

相關文章