到目前为止,我一直在考虑从Netty版本3.5.7.Final升级到4.0.0CR3,直到我在升级过程中遇到最后的问题...... LengthFieldBasedFrameDecoder。每个可用的构造函数都需要一个maxFrameLength,我将其设置为Integer.MAX_VALUE但是在运行客户端/服务器时,我得到几个堆栈跟踪(如下所示),表明已超出Integer.MAX_VALUE(2147483647)。我试图通过挖掘API文档中的ChannelConfig类和各种其他stackoverflow帖子来配置最大通道缓冲区大小,但仍然没有占上风。有没有人知道我可以设置一个缺少的选项,或者一种方法来阻止读取甚至是这么高?
堆栈追踪:
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);
使用扩展ChannelInitializer的自定义类重写initChannel方法
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);
}
答案 0 :(得分:0)
在netty中,将4个字节的长度字段转换为unsigned int(实际上是长的)
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。
代码:
int i = 0xF7BFFFE3;
System.out.println(i);
检查长度字段的值。
试试这个:
您的ChannelInitializer
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);
}
希望这有帮助。