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

TCP粘包/拆包java

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


TCP粘包/拆包問題說明code

客戶端要給服務端發送數據,假如爲兩個數據包。ip

可能的狀況以下:get


問題產生的緣由:it

1-應用程序write寫入的字節大小 大於 套接字發送緩衝區大小pip

2-進行MSS大小的TCP分段ast

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


TCP粘包/拆包解決辦法sed

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

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

3-消息分割,頭爲長度(消息總長度或消息體長度),一般頭用一個int32表示

4-複雜的應用層協議


Netty對於讀寫半包的的處理

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

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

//decoder
//1-讀半包的解碼器
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4)); 
//2-進行消息解碼
ch.pipeline().addLast(new ProtobufDecoder(BoxAuthReqProto.AuthRequest.getDefaultInstance()));
//encoder					
ch.pipeline().addLast(new LengthFieldPrepender(4));
ch.pipeline().addLast(new ProtobufEncoder());
相關文章
相關標籤/搜索