欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.

程序员文章站 2022-06-16 18:21:31
Netty解码器报错:XXXDecoder.decode() did not read anything but decoded a message.从字面意思来看,就是说没有读取任何数据,但是却解析出来了一个对象。1、问题引出在写自定义的基于String的解码器的时候,在使用该解码器进行解码的时候会抛出这个异常。对应的解码器代码很简单,就是将ByteBuf转化为一个字符串,然后添加到list中,供后面的handler进行处理。编码器代码也很简单,就是将字符串变成一个byte数组,写到Byt...

Netty解码器报错:XXXDecoder.decode() did not read anything but decoded a message.

从字面意思来看,就是说没有读取任何数据,但是却解析出来了一个对象。
【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.

1、问题引出

在写自定义的基于String的解码器的时候,在使用该解码器进行解码的时候会抛出这个异常。

  • 对应的解码器代码很简单,就是将ByteBuf转化为一个字符串,然后添加到list中,供后面的handler进行处理。
    【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.
  • 编码器代码也很简单,就是将字符串变成一个byte数组,写到ByteBuf中,供后面的handler进行处理。
    【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.

2、ByteToMessageDecoder源码解析

当有数据到来的时候,会调用handler的channelRead方法,代码逻辑很简单大概分为三步:

  • 读取字节流,累加字节流
  • 将读取到的字节流交由子类的decoder方法解析,也就是我们自定义的解码器
  • 将解析出来的对象继续向下传播
    【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.
    其中在调用子类decoder方法的时候,会有这么一段判断逻辑:
    【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.
  • 记录一下在解析之前list里面的对象数量。
  • 记录一下解析之前字节流里面可读的字节数。
  • 然后调用子类的解析方法
  • 调用之后,list里面的对象和之前的相等,说明没有解析出对象,此时分两种情况,一种没有读取到数据,另一种解析出部分数据但不够构成一个对象
  • 最后就来到异常抛出的地方,也就是解析出来了对象,但是bytebuf可读的字节容量和解析之前可读的字节数是相等的,换句话说就是明明解析出来了对象,但是没有读取走数据,因此这里会抛出异常。

那么为什么会进这个if呢?看自定义的解码器,只是单纯的将byteBuf转换成了一个String,byteBuf的readIndex并没有任何移动,因此byteBuf可读的字节数量在解析前后是相等的。

3、问题解决

知道了异常抛出的原因,这下解决它还是很简单的,只需要让byteBuf的readindex索引随读取的数据向前移动即可,因此可以有两种解决方式:

  • 将buteBuf里面的数据读取到放在一个byte数组中,然后,将byte数组转化为String向下传播,这样byteBuf的readIndex会向前移动的。
    【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.
  • 继续采用之前的方式,但是读取完之后,人为让readindex向前移动:
  • 【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.
    采用这两种方式,均可以完美解决问题。

4、MessageToMessageDecoder

String解码器的目的是把Byte解析为String,因此我们也可以继承MessageToMessageDecoder,泛型指定ByteBuf,也可以完成转换的需求,因为在这个类的channelRead中是直接调用子类的decoder方法,没有上面的那句if判断,因此自然也不会抛出那个问题:
【Netty报错原理和解决:】XXXDecoder.decode() did not read anything but decoded a message.
采用这种方式也可以解决问题。

本文地址:https://blog.csdn.net/weixin_43213517/article/details/110111326

相关标签: Netty java