[Netty 4 CR2]在使用用户定义的编码器和解码器关闭通道时发生异常

[Netty 4 CR2]在使用用户定义的编码器和解码器关闭通道时发生异常,netty,Netty,在我的项目中,我将用Netty4替换Netty3。我使用谷歌协议缓冲区作为数据传输。我在关闭频道时遇到了一个异常,它在Netty3中运行良好 以下是例外情况的详细信息: io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(4) exceeds writerIndex(0): PooledUnsafeDirectByteBuf(ridx: 0, w

在我的项目中,我将用Netty4替换Netty3。我使用谷歌协议缓冲区作为数据传输。我在关闭频道时遇到了一个异常,它在Netty3中运行良好

以下是例外情况的详细信息:

io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(4) exceeds writerIndex(0): PooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 4096)
    at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:95)
    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelInactive(DefaultChannelHandlerContext.java:801)
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelInactive(DefaultChannelHandlerContext.java:787)
    at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:808)
    at io.netty.channel.AbstractChannel$AbstractUnsafe$9.run(AbstractChannel.java:725)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:364)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:326)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:114)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IndexOutOfBoundsException: readerIndex(0) + length(4) exceeds writerIndex(0): PooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 4096)
    at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1120)
    at io.netty.buffer.AbstractByteBuf.readInt(AbstractByteBuf.java:627)
    at com.fhq.mathematica.netty.MMADecoder.decode(MMADecoder.java:17)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeLast(ByteToMessageDecoder.java:168)
    at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:91)
这是编码器:(消息是顶层协议缓冲区的接口。)

有人能解决这个问题吗?非常感谢


顺便说一句:我试过ObjectEncoder和ObjectDecoder,然后一切都很好。因此,我的解码器/编码器中一定存在一些问题。

在调用ByteBuf.readInt()之前,您需要检查是否有足够的字节可以读取

比如说:

public class MMADecoder extends ByteToMessageDecoder{
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in,
            MessageBuf<Object> out) throws Exception {
        if (in.readableBytes < 4) {
            return;
        }
        in.markReaderIndex();
        int dataLength = in.readInt();
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        byte[] decoded = new byte[dataLength];
        in.readBytes(decoded);
        out.add(MathematicaTask.parseFrom(decoded));
    }
}
公共类MMADecoder扩展为teToMessageDecoder{
@凌驾
受保护的无效解码(ChannelHandlerContext ctx、ByteBuf in、,
MessageBuf out)抛出异常{
if(in.readableBytes<4){
返回;
}
in.markReaderIndex();
int dataLength=in.readInt();
if(in.readableBytes()
谢谢!它起作用了!但是为什么我们要将可读字节与4进行比较呢?如果你有时间的话,你能看看这个问题吗?非常感激。[连结]
public class MMADecoder extends ByteToMessageDecoder{
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in,
            MessageBuf<Object> out) throws Exception {
        in.markReaderIndex();
        int dataLength = in.readInt();
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        byte[] decoded = new byte[dataLength];
        in.readBytes(decoded);
        out.add(MathematicaTask.parseFrom(decoded));
    }
}
int dataLength = in.readInt();
public class MMADecoder extends ByteToMessageDecoder{
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in,
            MessageBuf<Object> out) throws Exception {
        if (in.readableBytes < 4) {
            return;
        }
        in.markReaderIndex();
        int dataLength = in.readInt();
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        byte[] decoded = new byte[dataLength];
        in.readBytes(decoded);
        out.add(MathematicaTask.parseFrom(decoded));
    }
}