网易首页 > 网易号 > 正文 申请入驻

netty系列之:内置的Frame detection

0
分享至

简介

上篇文章我们讲到了netty中怎么自定义编码和解码器,但是自定义实现起来还是挺复杂的,一般没有特殊必要的情况下,大家都希望越简单越好,其难点就是找到ByteBuf中的分割点,将ByteBuf分割成为一个个的可以处理的单元。今天本文讲讲netty中自带的分割处理机制。

Frame detection

在上一章,我们提到了需要有一种手段来区分ByteBuf中不同的数据,也就是说找到ByteBuf中不同数据的分割点。如果首先将ByteBuf分割成一个个的独立的ByteBuf,再对独立的ByteBuf进行处理就会简单很多。

netty中提供了4个分割点的编码器,我们可以称之为Frame detection,他们分别是DelimiterBasedFrameDecoder, FixedLengthFrameDecoder, LengthFieldBasedFrameDecoder, 和 LineBasedFrameDecoder。

这几个类都是ByteToMessageDecoder的子类,接下来我们一一进行介绍。

DelimiterBasedFrameDecoder

首先是DelimiterBasedFrameDecoder,看名字就知道这个是根据delimiter对bytebuf进行分割的解码器。什么是delimiter呢?

netty中有一个Delimiters类,专门定义分割的字符,主要有两个delimiter,分别是nulDelimiter和lineDelimiter:

public static ByteBuf[] nulDelimiter() {
return new ByteBuf[] {
Unpooled.wrappedBuffer(new byte[] { 0 }) };

public static ByteBuf[] lineDelimiter() {
return new ByteBuf[] {
Unpooled.wrappedBuffer(new byte[] { '\r', '\n' }),
Unpooled.wrappedBuffer(new byte[] { '\n' }),
};
}

nullDelimiter用来处理0x00,主要用来处理Flash XML socket或者其他的类似的协议。

lineDelimiter用来处理回车和换行符,主要用来文本文件的处理中。

对于DelimiterBasedFrameDecoder来说,如果有多个delimiter的话,会选择将ByteBuf分割最短的那个,举个例子,如果我们使用DelimiterBasedFrameDecoder(Delimiters.lineDelimiter()) ,因为lineDelimiter中实际上有两个分割方式,回车+换行或者换行,如果遇到下面的情况:


| ABC\nDEF\r\n |

DelimiterBasedFrameDecoder会选择最短的分割结果,也就说将上面的内容分割成为:


| ABC | DEF |

而不是


| ABC\nDEF |
FixedLengthFrameDecoder

这个类会将ByteBuf分成固定的长度,比如收到了下面的4块byte信息:


| A | BC | DEFG | HI |

如果使用一个FixedLengthFrameDecoder(3) ,则会将上面的ByteBuf分成下面的几个部分:


| ABC | DEF | GHI |
LengthFieldBasedFrameDecoder

这个类就更加灵活一点,可以根据数据中的length字段取出后续的byte数组。LengthFieldBasedFrameDecoder非常灵活,它有4个属性来控制他们分别是lengthFieldOffset、lengthFieldLength、lengthAdjustment和initialBytesToStrip。

lengthFieldOffset是长度字段的起始位置,lengthFieldLength是长度字段本身的长度,lengthAdjustment是对目标数据长度进行调整,initialBytesToStrip是解密过程中需要删除的byte数目。理解不了?没关系,我们来举几个例子。

首先看一个最简单的:

lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 0

BEFORE DECODE (14 bytes) AFTER DECODE (14 bytes)
+--------+----------------+ +--------+----------------+
| Length | Actual Content |----->| Length | Actual Content |
| 0x000C | "HELLO, WORLD" | | 0x000C | "HELLO, WORLD" |
+--------+----------------+ +--------+----------------+

上面的设置表示,length是从第0位开始的,长度是2个字节。其中Ox00C=12, 这也是“HELLO, WORLD” 的长度。

如果不想要Length字段,可以通过设置initialBytesToStrip把length删除:

lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = 0
initialBytesToStrip = 2 (= length 字段的长度)

BEFORE DECODE (14 bytes) AFTER DECODE (12 bytes)
+--------+----------------+ +----------------+
| Length | Actual Content |----->| Actual Content |
| 0x000C | "HELLO, WORLD" | | "HELLO, WORLD" |
+--------+----------------+ +----------------+

lengthAdjustment是对Length字段的值进行调整,因为在有些情况下Length字段可能包含了整条数据的长度,也就是Length+内容,所以需要在解析的时候进行调整,比如下面的例子,真实长度其实是0x0C,但是传入的却是0x0E,所以需要减去Length字段的长度2,也就是将lengthAdjustment设置为-2。

lengthFieldOffset = 0
lengthFieldLength = 2
lengthAdjustment = -2 (= Length字段的长度)
initialBytesToStrip = 0

BEFORE DECODE (14 bytes) AFTER DECODE (14 bytes)
+--------+----------------+ +--------+----------------+
| Length | Actual Content |----->| Length | Actual Content |
| 0x000E | "HELLO, WORLD" | | 0x000E | "HELLO, WORLD" |
+--------+----------------+ +--------+----------------+
LineBasedFrameDecoder

LineBasedFrameDecoder专门处理文本文件中的一行结束。也就是 “\n” 和 “\r\n”,他和DelimiterBasedFrameDecoder很类似,但是DelimiterBasedFrameDecoder更加通用。

总结

有了上面4个Frame detection装置之后,就可以在pipline中首先添加这些Frame detection,然后再添加自定义的handler,这样在自定义的handler中就不用考虑读取ByteBuf的长度问题了。

比如在StringDecoder中,如果已经使用了 LineBasedFrameDecoder , 那么在decode方法中可以假设传入的ByteBuf就是一行字符串,那么可以直接这样使用:

protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception {
out.add(msg.toString(charset));

是不是很简单?

本文已收录于 http://www.flydean.com/15-netty-buildin-frame-detection/


特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
电影都不敢这么演!山东二男一女骑电动车抢金店,损失超1000万!

电影都不敢这么演!山东二男一女骑电动车抢金店,损失超1000万!

派大星纪录片
2024-11-29 16:39:23
中央决定,王浩进京履新

中央决定,王浩进京履新

鲁中晨报
2024-11-29 15:24:13
长寿最大的秘诀,不是运动,不是药补,而是这一个字

长寿最大的秘诀,不是运动,不是药补,而是这一个字

诗词中国
2024-11-29 12:51:23
俾路支恐怖分子傻眼了吧?直接被龙哥上了一堂现代化战争课。

俾路支恐怖分子傻眼了吧?直接被龙哥上了一堂现代化战争课。

现代小青青慕慕
2024-11-30 00:06:06
2025春晚进入倒计时,主题已官宣,赵本山、宋丹丹回归呼声高

2025春晚进入倒计时,主题已官宣,赵本山、宋丹丹回归呼声高

追风小狗
2024-11-29 16:20:24
2艘航母逼近中国家门口,解放军提前变阵,福建舰已到达指定位置

2艘航母逼近中国家门口,解放军提前变阵,福建舰已到达指定位置

空天力量
2024-11-28 19:53:18
欧冠输球仅1天!皇马变天,解雇安帅,52岁传奇接手,激活姆巴佩

欧冠输球仅1天!皇马变天,解雇安帅,52岁传奇接手,激活姆巴佩

绿茵舞着
2024-11-29 23:32:13
曾身居高位的王稼祥,为何在1962年时被勒令搬出中南海?

曾身居高位的王稼祥,为何在1962年时被勒令搬出中南海?

莲花盛开
2024-11-22 19:09:40
大结局要来?美防长曝出轰动性消息,李显龙紧急访华,中方要小心

大结局要来?美防长曝出轰动性消息,李显龙紧急访华,中方要小心

君君文谈
2024-11-28 18:29:17
网友们看出管晨辰和吴柳芳在本质上的不同了

网友们看出管晨辰和吴柳芳在本质上的不同了

清晖有墨
2024-11-29 19:52:48
妇产科医生马永红去世,年仅57岁,儿子发讣告,死因曝光太惋惜

妇产科医生马永红去世,年仅57岁,儿子发讣告,死因曝光太惋惜

180°视角
2024-11-29 22:23:44
传“江西年度最恐怖彩礼返还”,女方泡夜店搂人跳舞,判决19万彩礼退6万5

传“江西年度最恐怖彩礼返还”,女方泡夜店搂人跳舞,判决19万彩礼退6万5

小星球探索
2024-11-29 13:35:25
继卫生巾之后,粑粑柑也塌房了!网友:难道今年我就非死不可吗?

继卫生巾之后,粑粑柑也塌房了!网友:难道今年我就非死不可吗?

王大健美食日常
2024-11-29 18:17:24
优衣库:宁愿失去中国市场,也不使用新疆棉花

优衣库:宁愿失去中国市场,也不使用新疆棉花

映射生活的身影
2024-11-29 21:15:36
总裁的新家!C罗和乔治娜在利雅得搬家,新住处更小但更舒适豪华

总裁的新家!C罗和乔治娜在利雅得搬家,新住处更小但更舒适豪华

直播吧
2024-11-29 18:34:10
太难了!网传长沙邮政门口大量工人讨要工资,竟然又是外包引发…

太难了!网传长沙邮政门口大量工人讨要工资,竟然又是外包引发…

火山诗话
2024-11-29 15:44:24
被封杀4年的中国APP,印度政府还在用

被封杀4年的中国APP,印度政府还在用

观察者网
2024-11-29 11:38:07
中国对俄罗斯设备和化学品供应实施新制裁

中国对俄罗斯设备和化学品供应实施新制裁

桂系007
2024-11-30 00:30:47
真是出人意料!你没听错马斯克,竟然把陈年旧账翻了个底朝天

真是出人意料!你没听错马斯克,竟然把陈年旧账翻了个底朝天

玲子日记
2024-11-29 15:28:09
美国超市上架茅台?网友都瞅着看笑话,谁知看到单价:我们不配?

美国超市上架茅台?网友都瞅着看笑话,谁知看到单价:我们不配?

江湖一碗酒
2024-11-29 09:02:11
2024-11-30 04:55:00
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

"AGI不是大杀器,是普通人每天在用的产品"

头条要闻

男子疑因吃"驴打滚"窒息身亡 目击者:他无法吐出食物

头条要闻

男子疑因吃"驴打滚"窒息身亡 目击者:他无法吐出食物

体育要闻

穆雷与德约科维奇能凑成王炸组合吗?

娱乐要闻

叶珂被曝独自去产检,他俩真分了吗

财经要闻

专家建议将农民养老金提升至每月500元

汽车要闻

问界M7今年累计交付量已突破18万辆

态度原创

游戏
手机
健康
本地
公开课

钢岚:新版本三大专武分析!2.0版本难道究极凯皇即将降世?

手机要闻

华为Pura 80系列再次被确认:多焦段潜望加持,外围参数也已清晰

花18万治疗阿尔茨海默病,值不值?

本地新闻

云游中国|来伦布夏果感受充满Passion的人生

公开课

一块玻璃,如何改变人类世界?

无障碍浏览 进入关怀版