java - EmptyByteBuf出现在Netty服务器的Decoder链中

标签 java netty

Netty版本:5.0.0.Alpha2

以下是我向管道添加处理程序/解码器的方法。 (子处理程序)

childHandler(ch ->
    ch.pipeline().addLast(
      new LoggingHandler(LogLevel.TRACE),
      new LengthFieldBasedFrameDecoder(2048, 4, 2, -2, 0),
      new MyDecoder2(),
      new Encoder(),
      handler
    )
)

接下来我要做的就是向该服务器的输入发送一些垃圾。 LengthFieldBasedFrameDecoder 抛出 TooLongFrameException,这在本例中是预期的。

但是接下来发生的事情是,在 LengthFieldBasedFrameDecoder 抛出异常之后,使用 EmptyByteBuf 作为输入缓冲区调用 MyDecoder2.decode() 。 如果之前的解码器不返回任何内容,那么这个 EmptyByteBuf 从哪里来?

我希望 MyDecoder2 要么接收具有正确帧的 ByteBuf,由 LengthFieldBasedFrameDecoder 处理,要么什么也接收不到。

 Caused by: java.lang.IndexOutOfBoundsException: null
        at io.netty.buffer.EmptyByteBuf.checkIndex(EmptyByteBuf.java:866) ~[na:0.0]
        at io.netty.buffer.EmptyByteBuf.getBytes(EmptyByteBuf.java:317) ~[na:0.0]
        at spire.broker.proto.MyDecoder2.decode(MyDecoder2.java:27) ~[na:0.0]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeLast(ByteToMessageDecoder.java:371) ~[na:0.0]
        at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:275) ~[na:0.0]

也许我没有正确理解 Netty 如何与管道中的解码器链一起工作。

最佳答案

看一下 ByteToMessageDecoderchannelInactive() 方法的代码,该方法由 LengthFieldBasedFrameDecoder 扩展:

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    RecyclableArrayList out = RecyclableArrayList.newInstance();
    try {
        if (cumulation != null) {
            callDecode(ctx, cumulation, out);
            decodeLast(ctx, cumulation, out);
        } else {
            decodeLast(ctx, Unpooled.EMPTY_BUFFER, out);
        }
    } catch (DecoderException e) {
        throw e;
    } catch (Exception e) {
        throw new DecoderException(e);
    } finally {
        ...
    }
}

一旦 channel 变为非 Activity 状态,它将使用 Unpooled.EMPTY_BUFFER 最后一次调用解码方法。如果您制作了自定义解码器,这使您有机会进行清理。如果您对此不感兴趣,那么您需要重写 decodeLast() 方法以不执行任何操作。

关于java - EmptyByteBuf出现在Netty服务器的Decoder链中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30288897/

相关文章:

java - spring jdbc 模板返回空结果

java - 为什么此 java 邮件以纯文本而不是 html 形式到达收件人?

java - Netty:空闲状态处理程序不显示 channel 是否空闲

java - WebClient 与 RestTemplate SSL 连接

centos - 为什么我的基于 Netty 的 TCP 服务器在 100% CPU 使用率时挂起?

ssl - JBoss 网络 : Support for SNI (Server Name Indication)

java - Netty 4 从客户端创建多个连接

java - 改善 Android 应用程序 fragment 交易的加载时间

java - jdbc preparedStatement 的数字通配符?

java - 使用 Eclipse 和 OSGi 将类动态加载到 Java 类路径