前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LengthFieldBasedFrameDecoder解码器

LengthFieldBasedFrameDecoder解码器

作者头像
书唐瑞
发布2022-06-02 13:50:16
8160
发布2022-06-02 13:50:16
举报
文章被收录于专栏:Netty历险记

LengthFieldBasedFrameDecoder是一个基于长度解码器, 它是Netty提供的4个解码器中使用最广泛的一个解码器, RocketMQ中就是基于这个解码器进行解码消息的.

接下来分析下它是如何解码消息的. 在它的类中主要有4个属性:

代码语言:javascript
复制
private final int lengthFieldOffset;
private final int lengthFieldLength;
private final int lengthAdjustment;
private final int initialBytesToStrip;

只有真正理解这4个属性才能明白此解码器的强大功能.

为了描述, 我们先把数据构造下. 假如我们要发送'你好'这两个字, 转成16进制就是27b0597d.

此时客户端发送过来一串消息, 为了描述, 我们把消息转成16进制进行讲解:

0xDC00000A006327b0597d

对于上面的消息, 如何将其解码出来'你好'两个字呢? 即如何解码出来27b0597d, 就要使用到LengthFieldBasedFrameDecoder解码器, 那么我们就要设置上面的4个属性了.

代码语言:javascript
复制
lengthFieldOffset = 1
lengthFieldLength = 3
lengthAdjustment = -4
initialBytesToStrip = 6

(之所以为什么这几个属性要设置这几个数字,而不是其他数字, 其实是由消息结构和消息长度决定的)

我们说下每个值的含义:

lengthFieldOffset = 1表示长度域的偏移量是1, 那么从最开始向后移动1个字节, 就到了0xDC的后面位置; lengthFieldLength = 3表示长度域是3个字节, 在C的后面继续读取3个字节, 即读取到了0xDC00000A006327b0597d中的00000A, 00000A就是十进制10; lengthAdjustment = -4是调整长度, 就是用10+(-4)=6, 也就是说, 从A位置向后读取6个字节. 我们就读取到了0xDC00000A006327b0597d中的006327b0597d. 到目前为止, 我们总共读取到的字节是DC00000A006327b0597d, initialBytesToStrip = 6表示在原有消息的基础上从头跳过6个字节, 所以最后读取到的消息就是27b0597d, 也就是'你好'这两个字, 当然读取到的'你好'目前还是ByteBuf类型, 会把这个ByteBuf继续向下传播, 由接下来的业务解码器将其解码成字符串, 最后就是'你好'这两个字了.

整体思路:

1.从消息开头偏移lengthFieldOffset长度, 到达A位置

2.再从A位置读取lengthFieldLength长度, 到达B位置, 内容是d

3.再从B位置读取(d+lengthAdjustment)长度, 达到D位置

4.从消息开头跳过initialBytesToStrip长度到达C位置

5.将C位置-D位置之间的内容传送给接下来的处理器进行后续处理

用下面7个例子锻炼一下自己吧

1.

2.

3.

4.

5.

6.

7.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Netty历险记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档