Netty 4.01 CR6的稀疏越界问题



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

我们收到的消息格式包含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的新手,我怀疑这是我正在做的事情,但我不确定。

我希望有人能帮我解决这个问题。我更乐意发布更多信息来解决这个问题,只需询问即可。

感谢我在这件事上所能得到的一切帮助。

  • 蒂姆

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

客户端发送了无效数据,或者您的协议中并非所有数据包的消息中都包含STX

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

如果你想看到数据包流向解码器,你可以在解码器运行之前向管道添加一个LoggingHandler(LogLevel.INFO),这样它就会将原始字节打印为十六进制,这样你就可以检查它是否真的包含所需的字节序列。

旁注:您永远不会释放存储在msg中的字节。这将导致内存泄漏,并最终导致OOM,请确保在try-filly块中调用release,使其始终被称为

最新更新