netty 数据分包、组包、粘包处理机制(一)
2018-02-08 00:00
411 查看
摘要: netty 数据分包、组包、粘包处理机制(一)
包目录结构如下:
在数据传输中,我们发送的数据包如下所示
而实际接收的包的格式为:
产生的原因为:数据在传输过程中,产生数据包碎片(TCP/IP数据传输时大数据包无法一次传输,被拆分成小数据包,小数据包即为数据包碎片),这就造成了实际接收的数据包和发送的数据包不一致的情况。
而通过FrameDecoder即可实现对上述接收到的数据包的整理,重新还原成如下格式:
如下是一个自定义的Decoder类
此时,我们无需关注数据包是如何重组的,只需要做简单的验证(按照一个包验证)就可以了,FrameDecoder内部实现了组包的机制,不过,此时,需在数据的最前面封装整个数据的长度,示例中数据长度占了四个字节,即前四个字节是数据长度,后面的才是真实的数据。
此类的数据包按照指定的frame长度重新组包,比如确定长度为3,则组包为
构造方法为:new FixedLengthFrameDecoder(int frameLength);
frameLength即修正后的帧长度
另一个构造方法为new FixedLengthFrameDecoder(int frameLength, boolean allocateFullBuffer); allocateFullBuffer如果为真,则表示初始化的ChannelBuffer大小为frameLength。
对Flash XML的socket通信采用nulDelimiter()方法,对于一般的文本采用lineDelimiter()方法
如将以下数据包按照“\n”分隔:
即为:
而如果按照“\r\n”分隔,则为:
对于DelimiterBasedFrameDecoder中的构造方法,其中一些参数说明:
maxFrameLength:解码的帧的最大长度
stripDelimiter:解码时是否去掉分隔符
failFast:为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常
delimiter:分隔符
1. frame包整体功能描述
此包主要作用于对TCP/IP数据包的分包和包重组,常用于数据的流传输,是扩展的解码器。包目录结构如下:
2.包中各类功能详解
(1) FrameDecoder
抽象类,将ChannelBuffers中的二进制数据转换成有意义的数据帧(frame)对象,一般不直接调用,提供给此包中的FixedLengthFrameDecoder类、DelimiterBasedFrameDecoder类和LengthFieldBasedFrameDecoder类使用,也可以提供给其他类使用(暂不探讨);在数据传输中,我们发送的数据包如下所示
而实际接收的包的格式为:
产生的原因为:数据在传输过程中,产生数据包碎片(TCP/IP数据传输时大数据包无法一次传输,被拆分成小数据包,小数据包即为数据包碎片),这就造成了实际接收的数据包和发送的数据包不一致的情况。
而通过FrameDecoder即可实现对上述接收到的数据包的整理,重新还原成如下格式:
如下是一个自定义的Decoder类
public class MyFrameDecoder extends FrameDecoder { @Override protected Object decode(ChannelHandlerContext ctx, channel, ChannelBuffer buf) throws Exception { // Make sure if the length field was received. if (buf.readableBytes() < 4) { // The length field was not received yet - return null. // This method will be invoked again when more packets are // received and appended to the buffer. return null; } // The length field is in the buffer. // Mark the current buffer position before reading the length field // because the whole frame might not be in the buffer yet. // We will reset the buffer position to the marked position if // there's not enough bytes in the buffer. buf.markReaderIndex(); // Read the length field int length = buf.readInt(); // Make sure if there's enough bytes in the buffer. if (buf.readableBytes() < length) { // The whole bytes were not received yet - return null. // This method will be invoked again when more packets are // received and appended to the buffer. // Reset to the marked position to read the length field again // next time. buf.resetReaderIndex(); return null; } // There's enough bytes in the buffer. Read it. ChannelBuffer frame = buf.readBytes(length); // Successfully decoded a frame. Return the decoded frame. return frame; } }
此时,我们无需关注数据包是如何重组的,只需要做简单的验证(按照一个包验证)就可以了,FrameDecoder内部实现了组包的机制,不过,此时,需在数据的最前面封装整个数据的长度,示例中数据长度占了四个字节,即前四个字节是数据长度,后面的才是真实的数据。
(2) FixedLengthFrameDecoder
FixedLengthFrameDecoder主要是将诸如此类的数据包按照指定的frame长度重新组包,比如确定长度为3,则组包为
构造方法为:new FixedLengthFrameDecoder(int frameLength);
frameLength即修正后的帧长度
另一个构造方法为new FixedLengthFrameDecoder(int frameLength, boolean allocateFullBuffer); allocateFullBuffer如果为真,则表示初始化的ChannelBuffer大小为frameLength。
(3) Delimiters
分隔符类,DelimiterBasedFrameDecoder类的辅助类。对Flash XML的socket通信采用nulDelimiter()方法,对于一般的文本采用lineDelimiter()方法
(4) DelimiterBasedFrameDecoder
对接收到的ChannelBuffers按照指定的分隔符Delimiter分隔,分隔符可以是一个或者多个如将以下数据包按照“\n”分隔:
即为:
而如果按照“\r\n”分隔,则为:
对于DelimiterBasedFrameDecoder中的构造方法,其中一些参数说明:
maxFrameLength:解码的帧的最大长度
stripDelimiter:解码时是否去掉分隔符
failFast:为true,当frame长度超过maxFrameLength时立即报TooLongFrameException异常,为false,读取完整个帧再报异常
delimiter:分隔符
相关文章推荐
- netty 数据分包、组包、粘包处理机制(二)
- netty 数据分包、组包、粘包处理机制(一)
- netty 数据分包、组包、粘包处理机制(二)
- netty 数据分包、组包、粘包处理机制
- netty 数据分包、组包、粘包处理
- 通信(Netty、Mina2)【通信粘包的处理】、【数据协议】、【网络系统的安全性】
- netty学习之二 分包、组包、粘包处理
- 实例:Netty 处理 TCP协议数据分包问题
- netty之粘包分包的处理
- 实例:Netty 处理 TCP协议数据分包问题
- 通信(Netty、Mina2)【通信粘包的处理】、【数据协议】、【网络系统的安全性】
- 示例:Netty 处理 TCP数据分包协议
- python TCP Socket的粘包和分包的处理详解
- 即时通讯下数据粘包、断包处理实例(基于CocoaAsyncSocket)
- 数据接收中粘包及半包的处理
- 数据接收中粘包及半包的处理
- 数据接收中粘包及半包的处理
- netty处理粘包问题——2
- 即时通讯下数据粘包、断包处理实例(基于CocoaAsyncSocket)
- netty处理粘包问题用特殊字符分割——3