傻大方提要:【绝!真就一文全懂!Netty线程模型+启动详细分析+内存管理( 七 )】举个例子:假设操作系统已经接收到了三个包 , 如下: 文章插图 由于流传输的这个普通属性 , 在读取他们的时候将会存在很大的几率 , 这些数据会被...
按关键词阅读:
举个例子:假设操作系统已经接收到了三个包 , 如下:
文章插图
由于流传输的这个普通属性 , 在读取他们的时候将会存在很大的几率 , 这些数据会被分段成下面的几部分:
文章插图
也就是读取的数据有可能超过一个完整的数据包或者过多或者过少的半包 。
因此 , 作为一个接收方 , 不管它是服务端还是客户端 , 都需要把接收到的数据整理成一个或多个有意义的并且能够被应用程序容易理解的数据 。
拆包方案:
- 消息定长 , 固定报文长度 , 不够空格补全 , 发送和接收方遵循相同的约定 , 这样即使粘包了通过接收方编程实现获取定长报文也能区分 。
- 包尾添加特殊分隔符 , 例如每条报文结束都添加回车换行符(例如FTP协议)或者指定特殊字符作为报文分隔符 , 接收方通过特殊分隔符切分报文区分 。
- 将消息分为消息头和消息体 , 消息头中包含表示信息的总长度(或者消息体长度)的字段
- 定长解码器:FixedLengthFrameDecoder
ch.pipeline().addLast(new FixedLengthFrameDecoder(30));//设置定长解码器- 特殊分隔符解码器:DelimiterBasedFrameDecoder
ByteBuf delimiter = Unpooled.copiedBuffer("//1024表示单条消息的最大长度 , 解码器在查找分隔符的时候 , 达到该长度还没找到的话会抛异常ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter));- 基于包头不固定长度的解码器:LengthFieldBasedFrameDecoder
/** * maxFrameLength:解码的帧的最大长度 * lengthFieldOffset:长度属性的起始位(偏移位) , 包中存放有整个大数据包长度的字节 , 这段字节的其实位置 * lengthFieldLength:长度属性的长度 , 即存放整个大数据包长度的字节所占的长度 * lengthAdjustmen:长度调节值 , 在总长被定义为包含包头长度时 , 修正信息长度 。* initialBytesToStrip:跳过的字节数 , 根据需要我们跳过lengthFieldLength个字节 , 以便接收端直接接受到不含“长度属性”的内容 */ch.pipeline().addLast("decoder", new LengthFieldBasedFrameDecoder(MAX_FRAME_LENGTH, LENGTH_OFFSET,LENGTH_LEN, LENGTH_ADJUGEMENT, INIT_BYTE_TO_STRIP));参考资料资料名称 来源 《Netty实战》 图书 《Netty权威指南》 图书 Netty官网wiki netty.io/wiki/relate… 其他互联网资料链接
【绝!真就一文全懂!Netty线程模型+启动详细分析+内存管理】作者:Chopin1994链接:来源:掘金
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111J293N2020.html
标题:绝!真就一文全懂!Netty线程模型+启动详细分析+内存管理( 七 )