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 包头的更多相关文章

  1. 基于Java Netty框架构建高性能的部标808协议的GPS服务器

    使用Java语言开发一个高质量和高性能的jt808 协议的GPS通信服务器,并不是一件简单容易的事情,开发出来一段程序和能够承受数十万台车载接入是两码事,除去开发部标808协议的固有复杂性和几个月长周 ...

  2. Android Netty框架的使用

    Netty框架的使用 1 TCP开发范例 发送地址---192.168.31.241 发送端口号---9223 发送数据 { "userid":"mm910@mbk.co ...

  3. netty中LengthFieldBasedFrameDecoder的使用

    在org.jboss.netty.handler.codec.frame包中,有LengthFieldBasedFrameDecoder类用来解析带有长度属性的包,只要我们在传输协议中加入包的总长度就 ...

  4. Netty 对通讯协议结构设计的启发和总结

    Netty 通讯协议结构设计的总结 key words: 通信,协议,结构设计,netty,解码器,LengthFieldBasedFrameDecoder 原创 包含与机器/设备的通讯协议结构的设计 ...

  5. netty 粘包问题处理

    netty 粘包问题处理 key words: netty 粘包 解包 半包 TCP 一般TCP粘包/拆包解决办法 定长消息,例如每个报文长度固定,不够补空格 使用回车换行符分割,在包尾加上分割符,例 ...

  6. 服务端NETTY 客户端非NETTY处理粘包和拆包的问题

    之前为了调式和方便一直没有处理粘包的问题,今天专门花了时间来搞NETTY的粘包处理,要知道在高并发下,不处理粘包是不可能的,数据流的混乱会造成业务的崩溃什么的我就不说了.所以这个问题 在我心里一直是个 ...

  7. Netty之粘包分包

    粘包现象 客户端在一个for循环内连续发送1000个hello给Netty服务器端, Socket socket = new Socket("127.0.0.1", 10101); ...

  8. Netty自定义协议解析原理与应用

    目前,大家都选择Netty做为游戏服务器框架网络通信的框架,而且目前也有很多优秀的产品是基于Netty开发的.它的稳定性,易用性和高效率性已得到广泛的认同.在游戏服务器开发中,选择netty一般就意味 ...

  9. Netty 中 LengthFieldBasedFrameDecoder 构造函数取值备忘

    public LengthFieldBasedFrameDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, ...

随机推荐

  1. XSS代码注入框架

    首先需要了解一下几点: 1.浏览器中Javascript变量的生命周期 Javascript变量的生命周期并不是你声明这个变量个窗口闭就被回收,只要有引用就会一直持续到浏览器关闭. 2.window对 ...

  2. 在阿里云申请Symantec免费SSL证书操作流程

    2016年阿里云与国内证书颁发机构天威诚信推出了基于Symantec(赛门铁克)的免费SSL证书,有需要免费SSL证书产品的可以前往阿里云进行申请. 申请地址:阿里云云盾证书服务—Symantec免费 ...

  3. VM workstation 与 VM vSphere的区别 [转载]

    在学完vSphere后,想起了VMware Workstation.这两个都是虚拟化的东西,这两者到底有什么本质的不同呢?顺着我的思路我开始将所学过的进行检索期望从中寻到一丝半点的线索.很快大脑中建立 ...

  4. AngularJs(SPA)单页面SEO以及百度统计应用(下)

    苍苍之天不得久视,堂堂之地不得久履 当你小心翼翼的开启服务端渲染的同时,一个问题不得不注意,使用内存模式去保存渲染过的页面,这样服务断掉重启后,缓存也没有了,所以这里我们使用mongdodb进行本地化 ...

  5. VSCode配置简单的vue项目

    VSCode配置简单的vue项目 https://www.cnblogs.com/wnxyz8023/p/9989447.html 由于最近要使用的项目框架为前后端分离的,采用的是vue.js+web ...

  6. ubuntu下Sprak(IDE)wordcount例子

    一.进入IDE界面 cd ~/Downloads/idea/bin idea.sh 二.建立scala项目 Step 1:导入Spark-hadoop对应的包,次选择“File”–> “Proj ...

  7. 关于 facebook

    2017/10/29 Facebook账号分分钟被禁用,见怪不怪就好了,禁了就申诉呗 Facebook 如果遇到帐号被停用 / 帐号被封锁,大致上来说有叁个原因: 1, 名字用假名 2, 一个人拥有多 ...

  8. 文件基本操作 (C语言)

    一切皆文件 ---Linux 头文件 <stdio.h> 中定义了文件的相关操作 #include <stdio.h> 文件操作基本流程: 打开:fopen 相关操作 关闭:f ...

  9. Java string.valueof的用法以及与parseint的区别

    一.由基本数据型态转换成String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 ,也就是 String.valueOf() 这个参数多载的方法 有以下几 ...

  10. SOA和Web Servcie的区别

    soa(Service-Oriented Architecture)是服务对服务的,web service是服务对客户端的. 都提供服务.  服务接口都是基于开发的.  服务接口和服务的具体实现都是分 ...