Netty 包头
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)
BEFORE DECODE (14 bytes) AFTER DECODE (14 bytes)
+--------+----------------+ +--------+----------------+
| Length | Actual Content |---->| Length | Actual Content |
| 0x000C | "HELLO, WORLD" | | 0x000C | "HELLO, WORLD" |
+--------+----------------+ +--------+----------------+
此时数据格式不做任何改变(没有跳过任何字节)
2. 2 bytes length field at offset 0, strip header
lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 2 (= the length of the Length field)
BEFORE DECODE (14 bytes) AFTER DECODE (12 bytes)
+--------+----------------+ +----------------+
| Length | Actual Content |---->| Actual Content |
| 0x000C | "HELLO, WORLD" | | "HELLO, WORLD" |
+--------+----------------+ +----------------+
此时帧长度为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
BEFORE DECODE (14 bytes) AFTER DECODE (14 bytes)
+--------+----------------+ +--------+----------------+
| Length | Actual Content |---->| Length | Actual Content |
| 0x000E | "HELLO, WORLD" | | 0x000E | "HELLO, WORLD" |
+--------+----------------+ +--------+----------------+
此处定义的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
BEFORE DECODE (17 bytes) AFTER DECODE (17 bytes)
+---------+---------+--------------+ +---------+---------+------------+
| Header 1| Length |Actual Content|--->| Header 1| Length | Actual Content|
| 0xCAFE | 0x00000C|"HELLO, WORLD"| | 0xCAFE |0x00000C| "HELLO, WORLD"|
+---------+---------+--------------+ +----------+--------+-----------+
此处lengthFieldOffset = 2,从第3个字节开始表示数据长度,长度占3个字节,真实数据长度为0x00000C 即12个字节,而lengthAdjustment=0,initialBytesToStrip = 0,故解码后的数据与解码前的数据相同。
4. 3 bytes length field at the beginning of 5 bytes header, do not strip header
lengthFieldOffset = 0
lengthFieldLength = 3
lengthAdjustment = 2 (= the length of Header 1)
initialBytesToStrip = 0
BEFORE DECODE (17 bytes) AFTER DECODE (17 bytes)
+----------+----------+----------------+ +----------+----------+----------------+
| Length | Header 1 | Actual Content |----->| Length | Header 1 | Actual Content |
| 0x00000C | 0xCAFE | "HELLO, WORLD" | | 0x00000C | 0xCAFE | "HELLO, WORLD" |
+----------+----------+----------------+ +----------+----------+----------------+
此处由于修正的字节数是2,且initialBytesToStrip = 0,故整个数据的解码数据保持不变
总字节数是17,开始的三个字节表示字节长度:12,修正的字节是2,(即从第三个字节开始,再加两个开始是真正的数据,其中跳过的字节数是0)
5. 2 bytes length field at offset 1 in the middle of 4 bytes header, strip the first header field and the length field
lengthFieldOffset = 1 (= the length of HDR1)
lengthFieldLength = 2
lengthAdjustment = 1 (= the length of HDR2)
initialBytesToStrip = 3 (= the length of HDR1 + LEN)
BEFORE DECODE (16 bytes) AFTER DECODE (13 bytes)
+------+--------+------+----------------+ +------+----------------+
| HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
| 0xCA | 0x000C | 0xFE | "HELLO, WORLD" | | 0xFE | "HELLO, WORLD" |
+------+--------+------+----------------+ +------+----------------+
从第2个字节开始解码,取两个字节作为帧长度,为12个字节,然后,修正一个字节,从第5个字节到最后表示帧数据,解码时,由于initialBytesToStrip=3,表示跳过前三个字节(去掉),故从第四个字节开始解析,解析出来后,如右图所示。
6. 2 bytes length field at offset 1 in the middle of 4 bytes header, strip the first header field and the length field, the length field represents the length of the whole message
lengthFieldOffset = 1
lengthFieldLength = 2
lengthAdjustment = -3 (= the length of HDR1 + LEN, negative)
initialBytesToStrip = 3
BEFORE DECODE (16 bytes) AFTER DECODE (13 bytes)
+------+--------+------+----------------+ +------+----------------+
| HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
| 0xCA | 0x0010 | 0xFE | "HELLO, WORLD" | | 0xFE | "HELLO, WORLD" |
+------+--------+------+----------------+ +------+----------------+
从第二个字节开始,取两个字节作为帧长度,为16个字节,然后补3个字节,故往前找三个字节,从HDP1开始解码,而又因为initialBytesToStrip=3,解码时忽略掉前三个字节,故从第四个字节开始解析,解析结果如右图所示。
总结:一般来讲,当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));
Netty 包头的更多相关文章
- 基于Java Netty框架构建高性能的部标808协议的GPS服务器
使用Java语言开发一个高质量和高性能的jt808 协议的GPS通信服务器,并不是一件简单容易的事情,开发出来一段程序和能够承受数十万台车载接入是两码事,除去开发部标808协议的固有复杂性和几个月长周 ...
- Android Netty框架的使用
Netty框架的使用 1 TCP开发范例 发送地址---192.168.31.241 发送端口号---9223 发送数据 { "userid":"mm910@mbk.co ...
- netty中LengthFieldBasedFrameDecoder的使用
在org.jboss.netty.handler.codec.frame包中,有LengthFieldBasedFrameDecoder类用来解析带有长度属性的包,只要我们在传输协议中加入包的总长度就 ...
- Netty 对通讯协议结构设计的启发和总结
Netty 通讯协议结构设计的总结 key words: 通信,协议,结构设计,netty,解码器,LengthFieldBasedFrameDecoder 原创 包含与机器/设备的通讯协议结构的设计 ...
- netty 粘包问题处理
netty 粘包问题处理 key words: netty 粘包 解包 半包 TCP 一般TCP粘包/拆包解决办法 定长消息,例如每个报文长度固定,不够补空格 使用回车换行符分割,在包尾加上分割符,例 ...
- 服务端NETTY 客户端非NETTY处理粘包和拆包的问题
之前为了调式和方便一直没有处理粘包的问题,今天专门花了时间来搞NETTY的粘包处理,要知道在高并发下,不处理粘包是不可能的,数据流的混乱会造成业务的崩溃什么的我就不说了.所以这个问题 在我心里一直是个 ...
- Netty之粘包分包
粘包现象 客户端在一个for循环内连续发送1000个hello给Netty服务器端, Socket socket = new Socket("127.0.0.1", 10101); ...
- Netty自定义协议解析原理与应用
目前,大家都选择Netty做为游戏服务器框架网络通信的框架,而且目前也有很多优秀的产品是基于Netty开发的.它的稳定性,易用性和高效率性已得到广泛的认同.在游戏服务器开发中,选择netty一般就意味 ...
- Netty 中 LengthFieldBasedFrameDecoder 构造函数取值备忘
public LengthFieldBasedFrameDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, ...
随机推荐
- 使用Python自己实现简单的数据可视化
只使用Python的random库,将已有数据生成HTML格式的标签云.思路就是根据同一单词出现的次数多少,生成不同大小不同颜色单词的数据的视图. 比如以下格式的多条数据: 1 Gaming 1 Sk ...
- java8新特性详解(转)
原文链接. 前言: Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with ...
- Linux 生产实习01
Linux 生产实习01 标签(空格分隔): Linux 2018.07.02 相关软件下载地址:Linux Study 0x01. 安装 VMware Workstation VMware Work ...
- aria2
在之前我们已经介绍了通过uGet使用aria2来进行下载,但是这样只是使用aria2最简单的功能,现在我们来介绍一下aria2的常用命令 简单篇: 一般使用使用 aria2 下载文件,只需在命令后附加 ...
- 使用 JavaScript 编写优化算法 (1)
之前一直用Python来写优化算法,为了增强 JS 的熟练程度,开始将原有的代码改写成 JS.采用的工具包括 node.js + Grunt + nodeunit + github + npm + t ...
- ReentrantLock和AQS
AQS(AbstractQueuedSynchronizer)是JDK1.5提供的一个用来构建锁和同步工具的框架,子类包括常用的ReentrantLock.CountDownLatch.Semapho ...
- Django RESTful Web Services, 此书学DRF不错
全名为<Django RESTful Web Services: The easiest way to build Python RESTful APIs and web services wi ...
- 【AtCoder】Dwango Programming Contest V题解
A - Thumbnail 题意简述:给出N个数,找出N个数中和这N个数平均值绝对值最小的数 根据题意写代码即可= = #include <bits/stdc++.h> #define f ...
- 028 Partitioner:数据分区器
Partitioner:数据分区器,决定数据到下一个RDD的时候在那一个分区 HashPartitioner:根据key的hashCode值来实现 RangePartitioner: 根据key所属范 ...
- 浅谈2-SAT(待续)
2-SAT问题,其实是一个逻辑互斥问题.做了两道裸题之后仔细想来,和小时候做过的“有两个女生,如果A是女生,那么B一定不是女生.A和C性别相同,求A.B.C三人的性别.”几乎是一样的. 对于这道题我们 ...