Netty 4.0.0.CR3-LengthFieldBasedFrameDecoder maxFrameLength超过Integer.MAX_值

Netty 4.0.0.CR3-LengthFieldBasedFrameDecoder maxFrameLength超过Integer.MAX_值,netty,Netty,到目前为止,我一直对从Netty版本3.5.7.Final升级到4.0.0CR3感到焦虑,直到在升级过程中遇到最后一个问题。。。。LengthFieldBasedFrameDecoder。每个可用构造函数都需要一个maxFrameLength,我将其设置为Integer.MAX_值,但在运行客户机/服务器时,我会得到几个堆栈跟踪(如下所示),其中一个堆栈跟踪表明已超过Integer.MAX_值(2147483647)。我试图通过在API文档和各种其他stackoverflow文章中挖掘Chann

到目前为止,我一直对从Netty版本3.5.7.Final升级到4.0.0CR3感到焦虑,直到在升级过程中遇到最后一个问题。。。。LengthFieldBasedFrameDecoder。每个可用构造函数都需要一个maxFrameLength,我将其设置为Integer.MAX_值,但在运行客户机/服务器时,我会得到几个堆栈跟踪(如下所示),其中一个堆栈跟踪表明已超过Integer.MAX_值(2147483647)。我试图通过在API文档和各种其他stackoverflow文章中挖掘ChannelConfig类来配置最大通道缓冲区大小,但仍然没有成功。有人知道我是否可以设置一个缺失的选项,或者一种方法来防止读取量达到这么高吗

堆栈跟踪:

io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 2147483647: 4156555235 - discarded
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:486)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:462)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:397)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:352)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:111)
at io.netty.handler.codec.ByteToMessageDecoder.inboundBufferUpdated(ByteToMessageDecoder.java:69)
at io.netty.channel.ChannelInboundByteHandlerAdapter.inboundBufferUpdated(ChannelInboundByteHandlerAdapter.java:46)
at io.netty.channel.DefaultChannelHandlerContext.invokeInboundBufferUpdated(DefaultChannelHandlerContext.java:1031)
at io.netty.channel.DefaultChannelHandlerContext.fireInboundBufferUpdated0(DefaultChannelHandlerContext.java:998)
at io.netty.channel.DefaultChannelHandlerContext.fireInboundBufferUpdated(DefaultChannelHandlerContext.java:978)
at io.netty.handler.timeout.IdleStateHandler.inboundBufferUpdated(IdleStateHandler.java:257)
at io.netty.channel.DefaultChannelHandlerContext.invokeInboundBufferUpdated(DefaultChannelHandlerContext.java:1057)
at io.netty.channel.DefaultChannelHandlerContext.fireInboundBufferUpdated0(DefaultChannelHandlerContext.java:998)
at io.netty.channel.DefaultChannelHandlerContext.fireInboundBufferUpdated(DefaultChannelHandlerContext.java:978)
at io.netty.channel.DefaultChannelPipeline.fireInboundBufferUpdated(DefaultChannelPipeline.java:828)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:118)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:429)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:392)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:322)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:114)
at java.lang.Thread.run(Thread.java:680)
我的客户端配置如下:

peerClient.bootstrap = new Bootstrap();

peerClient.bootstrap.group(new NioEventLoopGroup())
          .channel(NioSocketChannel.class)
          .option(ChannelOption.ALLOCATOR, UnpooledByteBufAllocator.DEFAULT)
          .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 120000)
          .option(ChannelOption.SO_KEEPALIVE, true)
          .option(ChannelOption.TCP_NODELAY, true)
          .option(ChannelOption.SO_REUSEADDR, true)
          .handler(PeerInitializer.newInstance());
我的服务器配置:

result.serverBootstrap = new ServerBootstrap();

result.serverBootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
      .channel(NioServerSocketChannel.class)
      .handler(new LoggingHandler(LogLevel.INFO))
      .childHandler(PeerInitializer.newInstance())
      .childOption(ChannelOption.ALLOCATOR, UnpooledByteBufAllocator.DEFAULT);
initChannel方法被自定义类扩展的ChannelInitializer重写

public class PeerInitializer extends ChannelInitializer<SocketChannel>

@Override
protected void initChannel(SocketChannel ch) throws Exception {
    final ChannelPipeline pipeline = ch.pipeline();

    pipeline.addLast(
            messageEncoder,
            HandshakeDecoder.newInstance(),
            connectionHandler,
            handshakeHandler,
            new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4),
            messageHandler);
}
public class PeerInitializer extends ChannelInitializer<SocketChannel>

@Override
protected void initChannel(SocketChannel ch) throws Exception {
    final ChannelPipeline pipeline = ch.pipeline();

    pipeline.addLast(
            new ByteLoggingHandler(LogLevel.INFO), // add
            messageEncoder,
            HandshakeDecoder.newInstance(),
            connectionHandler,
            handshakeHandler,
            new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4),
            messageHandler);
}
公共类PeerInitializer扩展了通道初始值设定项
@凌驾
受保护的void initChannel(SocketChannel ch)引发异常{
最终通道管道=通道管道();
pipeline.addLast(
消息编码器,
握手编码器。newInstance(),
连接处理器,
握手手,
新的LengthFieldBasedFrameDecoder(Integer.MAX_值,0,4),
messageHandler);
}

在netty中,将4字节长度字段转换为无符号整数(实际长度)

LengthFieldBasedFrameDecoder.java

private long getFrameLength(ByteBuf in, int actualLengthFieldOffset) {
    in = in.order(byteOrder);
    long frameLength;
    switch (lengthFieldLength) {
    case 1:
        frameLength = in.getUnsignedByte(actualLengthFieldOffset);
        break;
    case 2:
        frameLength = in.getUnsignedShort(actualLengthFieldOffset);
        break;
    case 3:
        frameLength = in.getUnsignedMedium(actualLengthFieldOffset);
        break;
    // This Code
    case 4:
        frameLength = in.getUnsignedInt(actualLengthFieldOffset);
        break;
    case 8:
        frameLength = in.getLong(actualLengthFieldOffset);
        break;
    default:
        throw new Error("should not reach here");
    }
    return frameLength;
}
AbstractByteBuf.java

@Override
public long getUnsignedInt(int index) {
    return getInt(index) & 0xFFFFFFFFL;
}
4156555235是-138412061

代码:

检查长度字段的值

试试这个:

你的通道初始化器

public class PeerInitializer extends ChannelInitializer<SocketChannel>

@Override
protected void initChannel(SocketChannel ch) throws Exception {
    final ChannelPipeline pipeline = ch.pipeline();

    pipeline.addLast(
            messageEncoder,
            HandshakeDecoder.newInstance(),
            connectionHandler,
            handshakeHandler,
            new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4),
            messageHandler);
}
public class PeerInitializer extends ChannelInitializer<SocketChannel>

@Override
protected void initChannel(SocketChannel ch) throws Exception {
    final ChannelPipeline pipeline = ch.pipeline();

    pipeline.addLast(
            new ByteLoggingHandler(LogLevel.INFO), // add
            messageEncoder,
            HandshakeDecoder.newInstance(),
            connectionHandler,
            handshakeHandler,
            new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4),
            messageHandler);
}
公共类PeerInitializer扩展了通道初始值设定项
@凌驾
受保护的void initChannel(SocketChannel ch)引发异常{
最终通道管道=通道管道();
pipeline.addLast(
新建ByteLoggingHandler(LogLevel.INFO),//添加
消息编码器,
握手编码器。newInstance(),
连接处理器,
握手手,
新的LengthFieldBasedFrameDecoder(Integer.MAX_值,0,4),
messageHandler);
}
希望这有帮助