Netty(三):网络传输中的拆包、粘包问题
来源:互联网 发布:多因子选股 知乎 编辑:程序博客网 时间:2024/06/08 12:49
问题来源:
在Netty中对于TCP传输的默认数据大小为1024字节,当数据包不超过1024时,会一次接收完毕,当超过1024时,首先会进行拆分,即分成几次传输,等到下次连接时将会改变一次发包的数据大小为2048字节,然后下次增长为3072字节,然后下次增长为4096字节;然而,再往下增长,则增长了2048字节变为6144字节,然后变为8192字节(8KB),当数据再大时,接收到的数据包也不再改变。此后,只要发送的数据包大小不超过8192字节,便不再分包。
当一次连接的数据被分成几次进行传输时就带来一个问题:channelPipeline会把数据储存起来,然后每一次收到服务端发回来的数据时,将会触发一次channelRead方法,然后就会对收到的数据进行解析(因为此刻认为数据已经传输完毕,然而实际并没有),那么因为是拆分的数据所以就会导致解析失败!
解决方案:
在初始化bootstrap(启动器)时,要进行handler的注册,handler是以责任链的设计模式设计的,即channel读取时按照头handler——尾handler的流程,channel写入时按照尾handler——头handler的流程。所以我们必须在触发channelRead方法前先对数据进行处理,所以提出以下解决方案:在处理数据的handler之前注册一个decode的handler来保证接受到的数据的完整性。
这里的decode方法继承自ByteToMessageDecoder类。因为项目开发基于腾讯的Tars框架,从Tars框架源码(https://github.com/Tencent/Tars)中我们可以看到:
public static IoBuffer encodeResponse(TarsServantResponse response, String charsetName) throws ProtocolException { …… …… ByteBuffer buffer = jos.getByteBuffer(); int datalen = buffer.position(); buffer.position(0); buffer.putInt(datalen); buffer.position(datalen); return IoBuffer.wrap(jos.toByteArray());}
在encodeResponse方法中,最后将整个数据长度放入了缓冲区的开头。那么我们在decode的时候就可以先读取数据的长度,然后限制数据的读入长度,得到完整的数据后再进行处理。处理框图如下:
具体代码如下:
public class CommunicateDecoder extends ByteToMessageDecoder { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { int length = in.getInt(0);// Logs.access.info(">>>>>>>>> length is : {}", length); if(in.readableBytes() >= length) {// Logs.access.info(">>>>>>>>> in is : {}", in); ByteBuf unPool = Unpooled.buffer(length); in.readBytes(unPool, length);// Logs.access.info(">>>>>>>>> in after read is : {}", in);// Logs.access.info(">>>>>>>>> unPool is : {}", unPool); out.add(unPool); // unPool// Logs.access.info(">>>>>>>>> ready to send!"); } }}
- Netty(三):网络传输中的拆包、粘包问题
- netty解决TCP网络传输中的拆包与粘包问题
- netty中的粘包和拆包问题处理
- Netty实践(二):TCP拆包、粘包问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输"粘包"问题
- 解决TCP网络传输“粘包”问题
- 解决TCP网络传输“粘包”问题
- Socket编程
- 肖特基钳位
- 读书笔记--USB枚举过程
- Two Sum
- 连接服务器
- Netty(三):网络传输中的拆包、粘包问题
- Treap学习笔记
- 拨开字符编码的迷雾--编译器如何处理文件编码
- 面试题目: 求1+2+3+4+......+172+173
- Python自学笔记
- UVA
- python(四):numpy快速数据处理
- py-charm延长试用期限
- 享元模式