Netty自定义解码器解决粘包、数据异常读取等问题

Netty自定粘包解码器

netty粘包处理
netty提供了多种编码器用于处理半包,这些编码器包含
LineBasedFrameDecoder 换行解码器
DelimiterBasedFrameDecoder 分隔符解码器
FixedLengthFrameDecoder 定长解码器

各种解码器使用场景此处就不做介绍,想了解的可以自行官网或者google
基于自定义协议的解码器其实可以根据DelimiterBasedFrameDecoder来实现,但是这个解码器在实际使用中不是那么合适.有如下几个场景:

  1. 16进制的自定义协议
  2. 现有解码器无法满足的场景
  3. DelimiterBasedFrameDecoder 自定义分包符分包异常,数据读取异常等

在前段时间因为对DelimiterBasedFrameDecoder不太了解,结果把自己给坑了把
和硬件同事(C语言大佬)根据使用场景定了个协议包,包头以0XFF 0XFE开头 XXX结尾
大致协议是这样的
整体报文: 包头+报体+校验位(crc)
包头两个字节: 0XFF 0XFE
报体: N个字节
校验位: 2个字节
简单来讲就是要通过0XFF 0XFE来分包,碰到这两个字节在一起就一刀两半,校验位不是重点此处忽略
在使用DelimiterBasedFrameDecoder 的使用遇到问题如下:

1.分包异常
2.数据脏读

具体代码如下:
配置DelimiterBasedFrameDecoder解码器,最大长度1024,使用0xff 0xfe分包在handler里打印出结果

在这里插入图片描述
在这里插入图片描述

启动服务端,启动模拟客户端发送数据
FF FE 11 22 33 FF FE 44 55 66

在这里插入图片描述

第一次连接并发送数据输出结果如下:

在这里插入图片描述
数据只有一半?那再来发送一次同样的数据看看
在这里插入图片描述
第二次输出就对了 是不是很诡异? 试了几次只要传输的内容改变这个问题就会出现
换个思路想想有没可能是分隔符放置的问题? 那我们来试试
客户端的发送数据改为
11 22 33 FF FE 44 55 66 FF FE 77 88 FF FE

输出结果如下
在这里插入图片描述

哈哈,第一次连接发送数据和第二次发送输出结果都没有问题 到这里是不是结束了?答案当然是 没有
那我们再试试这种场景
客户端的发送数据改为
11 22 33 FF FE 44 55 66 FF FE 77 88 FF FE 99 00

两次输出结果如下:
在这里插入图片描述

WTF???
这种方式必然是不行的,至于为什么会出现这个问题有性趣的可以去看下DelimiterBasedFrameDecoder中的decode逻辑
那这个问题怎么解决呢
鄙人不才没能在DelimiterBasedFrameDecoder的基础上解决这个问题,只有另辟新路自定义解码器
查看DelimiterBasedFrameDecoder是继承ByteToMessageDecoder(大多数解码器都是这个类的派生类)主要是实现decode方法 那我们可以依葫芦画瓢

在这里插入图片描述
在这里插入图片描述

新建个类继承ByteToMessageDecoder实现decode抽象方法
在这里插入图片描述

然后自己实现decode方法,大致实现如下

在这里插入图片描述

在这里插入图片描述

测试验证

根据上面的3种场景,客户端发送的数据依次为
FF FE 11 22 33 FF FE 44 55 66

结果
在这里插入图片描述

11 22 33 FF FE 44 55 66 FF FE 77 88 FF FE
结果
在这里插入图片描述

11 22 33 FF FE 44 55 66 FF FE 77 88 FF FE 99 00
结果

在这里插入图片描述

如果对于第二和第三种前面没有以0xff 0xfe开头的数据也想保留的话则需在decode逻辑里把firstHead设置默认为true就可以了

在这里插入图片描述
好了鄙人技术有限 目前想到的解决方案只有这么多,如果有更好方案的大佬或者上面有误的地方万望不吝赐教o(∩_∩)o 哈哈

自己选的路,跪着也要走完,

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值