【问题标题】:Sparodic OutOfBounds issue with Netty 4.01 CR6Netty 4.01 CR6 的偶发性 OutOfBounds 问题
【发布时间】:2016-08-03 21:24:50
【问题描述】:

我开发的自定义解码器有问题,我不确定自己做错了什么。

我们收到的消息格式包含 HEADER、BODY 和 TRAILER。标头是 1 个字节,是一个 STX (0x02) 主体是可变长度的 尾部是 2 个字节,其中包含一个 ETX(0x03),后跟一个 LRC。

因此,典型的消息可能如下所示:

STX   BODY   ETX  LRC
02  37000000 06   18

解码器的输出应该是没有 STX 控制字节的消息。所以正在发送的消息是:

BODY     ETX  LRC
37000000 06   18

我们扩展了 DelimiterBasedFrameDecoder 并将 ETX 定义为分隔符。解码器的意图是读取下一个字节,将其添加到缓冲区,然后继续发送,这样我们就发送了完整的消息。我们的解码方法如下所示:

protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
    Object frame = super.decode(ctx, buffer);

    if (frame == null) {
        return null;
    }
    ByteBuf msg = null;

    if (frame instanceof ByteBuf) {
        msg = Unpooled.copiedBuffer((ByteBuf) frame);
        msg.writeByte(buffer.readByte());
        ((ByteBuf) frame).release();
    }

    while (msg.getByte(0) != STX) {
        msg.readByte();
        msg = msg.discardReadBytes();
    }

    return msg;
}

一切都按预期工作,除了我们定期收到以下异常。

java.lang.IndexOutOfBoundsException: readerIndex(225) + length(1) exceeds writerIndex(225): UnpooledUnsafeDirectByteBuf(ridx: 225, widx: 225, cap: 256)

我们使用的是 Netty 4.01 CR6,这是一个零星的问题。我不确定,这是我做的不对,还是 Netty 内部的问题。由于我对 Netty 很陌生,我怀疑这是我正在做的事情,但我不确定。

我希望有人可以帮助我解决这个问题。我很乐意发布更多信息来解决这个问题,请问。

感谢我在这方面能得到的任何帮助。

  • 蒂姆

【问题讨论】:

    标签: netty indexoutofboundsexception decoder


    【解决方案1】:

    这个异常意味着你试图从 bytebuf 中读取一个不包含的字节,因为你到达了它的末尾。

    要么是客户端发送了无效数据,要么不是你的协议中的所有数据包都在消息中包含STX

    解码现有协议时通常会犯的另一个错误是,您用作分隔符的字节序列在数据包本身内部使用,并且您应该逐字节读取数据包。

    如果您想查看流向解码器的数据包,您可以在解码器运行之前将LoggingHandler(LogLevel.INFO) 添加到管道中,以便它将原始字节打印为十六进制,以便您检查是否它实际上包含所需的字节序列。

    旁注:您永远不会释放存储在 msg 中的 bytebuf。这将造成内存泄漏并最终导致 OOM,请确保在 try-finally 块中调用 release,以便始终调用它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-04
      • 2020-05-16
      • 2013-06-26
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多