netty 数据分包、组包、粘包处理机制(二)
2018-02-08 00:00
344 查看
摘要: netty 数据分包、组包、粘包处理机制(二)
maxFrameLength:解码的帧的最大长度
lengthFieldOffset :长度属性的起始位(偏移位),包中存放有整个大数据包长度的字节,这段字节的其实位置
lengthFieldLength:长度属性的长度,即存放整个大数据包长度的字节所占的长度
lengthAdjustmen:长度调节值,在总长被定义为包含包头长度时,修正信息长度。
initialBytesToStrip:跳过的字节数,根据需要我们跳过lengthFieldLength个字节,以便接收端直接接受到不含“长度属性”的内容
failFast :为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常
下面对各种情况分别描述:
1. 2 bytes length field at offset 0, do not strip header
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 0 (= do not strip header) 不取消头部信息
此时数据格式不做任何改变(没有跳过任何字节)
2. 2 bytes length field at offset 0, strip header
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 2 (= the length of the Length field) 取消的初始字节数
此时帧长度为14个字节,但由于前(lengthFieldOffset = 0)两个(lengthFieldLength = 2)字节是表示帧长度的字节,不计入数据,故真实的数据长度为12个字节。
3. 2 bytes length field at offset 0, do not strip header, the length field represents the length of the whole message
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = -2 (= the length of the Length field) 调整需要解码的字节长度
initialBytesToStrip = 0
此处定义的Length为0x000E共占了两个字节,表示的帧长度为14个字节,前(lengthFieldOffset = 0)两个(lengthFieldLength = 2)字节为Length,由于设置的lengthAdjustment = -2 (= the length of the Length field),故修正的信息实际长度补2,即解码时往前推2个字节,解码后还是14个字节长度(此种情况是把整个长度封装,一般来讲,我们只封装数据长度)
4. 3 bytes length field at the end of 5 bytes header, do not strip header
lengthFieldOffset = 2 (= the length of Header 1)
lengthFieldLength = 3
lengthAdjustment = 0
initialBytesToStrip = 0
此处lengthFieldOffset = 2,从第3个字节开始表示数据长度,长度占3个字节,真实数据长度为0x00000C 即12个字节,而lengthAdjustment=0,initialBytesToStrip = 0,故解码后的数据与解码前的数据相同。
总结:一般来讲,当lengthAdjustment 为负数时,Length表示的是整个帧的长度,当lengthAdjustment为正数或0时,表示真实数据长度。
+----------------+
| "HELLO, WORLD" |
+----------------+
格式的数据转换成
+--------+--------------------+
+ 0x000C | "HELLO, WORLD" |
+--------+--------------------+
格式的数据,如果lengthIncludesLengthFieldLength设置为true,则编码为
+--------+--------------------+
+ 0x000E | "HELLO, WORLD" |
+--------+--------------------+
格式的数据
应用场景:自定义pipelineFactory类: MyPipelineFactory implements ChannelPipelineFactory中
pipeline.addLast("frameEncode", new LengthFieldPrepender(4, false));
在客户端设置pipeline.addLast("encoder", new LengthFieldPrepender(4, false));
pipeline.addLast("handler", new MyHandler());
前四个字节表示真实的发送的数据长度Length,编码时会自动加上;
在服务器端设置pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
真实数据最大字节数为Integer.MAX_VALUE,解码时自动去掉前面四个字节
(5) LengthFieldBasedFrameDecoder
常用的处理大数据分包传输问题的解决类,先对构造方法LengthFieldBasedFrameDecoder中的参数做以下解释说明“maxFrameLength:解码的帧的最大长度
lengthFieldOffset :长度属性的起始位(偏移位),包中存放有整个大数据包长度的字节,这段字节的其实位置
lengthFieldLength:长度属性的长度,即存放整个大数据包长度的字节所占的长度
lengthAdjustmen:长度调节值,在总长被定义为包含包头长度时,修正信息长度。
initialBytesToStrip:跳过的字节数,根据需要我们跳过lengthFieldLength个字节,以便接收端直接接受到不含“长度属性”的内容
failFast :为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常
下面对各种情况分别描述:
1. 2 bytes length field at offset 0, do not strip header
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 0 (= do not strip header) 不取消头部信息
此时数据格式不做任何改变(没有跳过任何字节)
2. 2 bytes length field at offset 0, strip header
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 2 (= the length of the Length field) 取消的初始字节数
此时帧长度为14个字节,但由于前(lengthFieldOffset = 0)两个(lengthFieldLength = 2)字节是表示帧长度的字节,不计入数据,故真实的数据长度为12个字节。
3. 2 bytes length field at offset 0, do not strip header, the length field represents the length of the whole message
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = -2 (= the length of the Length field) 调整需要解码的字节长度
initialBytesToStrip = 0
此处定义的Length为0x000E共占了两个字节,表示的帧长度为14个字节,前(lengthFieldOffset = 0)两个(lengthFieldLength = 2)字节为Length,由于设置的lengthAdjustment = -2 (= the length of the Length field),故修正的信息实际长度补2,即解码时往前推2个字节,解码后还是14个字节长度(此种情况是把整个长度封装,一般来讲,我们只封装数据长度)
4. 3 bytes length field at the end of 5 bytes header, do not strip header
lengthFieldOffset = 2 (= the length of Header 1)
lengthFieldLength = 3
lengthAdjustment = 0
initialBytesToStrip = 0
此处lengthFieldOffset = 2,从第3个字节开始表示数据长度,长度占3个字节,真实数据长度为0x00000C 即12个字节,而lengthAdjustment=0,initialBytesToStrip = 0,故解码后的数据与解码前的数据相同。
总结:一般来讲,当lengthAdjustment 为负数时,Length表示的是整个帧的长度,当lengthAdjustment为正数或0时,表示真实数据长度。
(6) LengthFieldPrepender
编码类,自动将+----------------+
| "HELLO, WORLD" |
+----------------+
格式的数据转换成
+--------+--------------------+
+ 0x000C | "HELLO, WORLD" |
+--------+--------------------+
格式的数据,如果lengthIncludesLengthFieldLength设置为true,则编码为
+--------+--------------------+
+ 0x000E | "HELLO, WORLD" |
+--------+--------------------+
格式的数据
应用场景:自定义pipelineFactory类: MyPipelineFactory implements ChannelPipelineFactory中
pipeline.addLast("frameEncode", new LengthFieldPrepender(4, false));
(7) TooLongFrameException
定义的数据包超过预定义大小异常类(8) CorruptedFrameException
定义的数据包损坏异常类3. frame包应用demo
解决分包问题,通常配置MyPipelineFactory中设置,示例如下:public class MyPipelineFactory implements ChannelPipelineFactory { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast("encoder", new LengthFieldPrepender(4, false)); pipeline.addLast("handler", new MyHandler()); return pipeline; } }
在客户端设置pipeline.addLast("encoder", new LengthFieldPrepender(4, false));
pipeline.addLast("handler", new MyHandler());
前四个字节表示真实的发送的数据长度Length,编码时会自动加上;
在服务器端设置pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
真实数据最大字节数为Integer.MAX_VALUE,解码时自动去掉前面四个字节
相关文章推荐
- netty 数据分包、组包、粘包处理机制(一)
- netty 数据分包、组包、粘包处理机制(一)
- netty 数据分包、组包、粘包处理机制(二)
- netty 数据分包、组包、粘包处理机制
- netty 数据分包、组包、粘包处理
- 通信(Netty、Mina2)【通信粘包的处理】、【数据协议】、【网络系统的安全性】
- 实例:Netty 处理 TCP协议数据分包问题
- netty学习之二 分包、组包、粘包处理
- 实例:Netty 处理 TCP协议数据分包问题
- 通信(Netty、Mina2)【通信粘包的处理】、【数据协议】、【网络系统的安全性】
- netty之粘包分包的处理
- 示例:Netty 处理 TCP数据分包协议
- Netty5用户手册之五:netty中流数据的传输处理问题
- 数据接收中粘包及半包的处理
- Spark大数据处理之从WordCount看Spark大数据处理的核心机制(1)
- Yii中Flash数据的处理机制(源码分析)
- TCP分包方法 && 粘包处理策略
- 从WordCount看Spark大数据处理的核心机制(2)
- Netty(三)TCP粘包拆包处理
- 数据分包处理