首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在数据包系统中使用Netty时出现java.lang.IndexOutOfBoundsException异常

在数据包系统中使用Netty时出现java.lang.IndexOutOfBoundsException异常
EN

Stack Overflow用户
提问于 2021-05-17 23:19:45
回答 1查看 290关注 0票数 0

我目前正在编写一个通过数据包进行通信的系统。这也是可行的。我只有一台服务器和理论上无限的客户端。当我只启动一个客户端时,它工作得很好,但是当我启动几个客户端时,我总是在程序工作了2-3分钟后得到一个java.lang.IndexOutOfBoundsException异常。

例外情况

代码语言:javascript
复制
WARNUNG: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(77) + length(36) exceeds writerIndex(112): PooledUnsafeDirectByteBuf(ridx: 77, widx: 112, cap: 112)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:478)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795)
        at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

Caused by: java.lang.IndexOutOfBoundsException: readerIndex(77) + length(36) exceeds writerIndex(112): PooledUnsafeDirectByteBuf(ridx: 77, widx: 112, cap: 112)
        at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1442)
        at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1428)
        at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:895)
        at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:903)
        at eu.diamondcloudservice.wrapper.packets.incoming.PacketInCloudServerConnect.read(PacketInCloudServerConnect.java:79)
        at eu.diamondcloudservice.wrapper.network.PacketDecoder.decode(PacketDecoder.java:21)
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)
        ... 19 more

服务器main(String[] args)

代码语言:javascript
复制
EventLoopGroup eventLoopGroup = epoll ? (EventLoopGroup) new EpollEventLoopGroup() : (EventLoopGroup) new NioEventLoopGroup();
    try {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(eventLoopGroup);
        serverBootstrap.channel(epoll ? EpollServerSocketChannel.class : NioServerSocketChannel.class);
        serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
            protected void initChannel(Channel channel) throws Exception {
                channel.pipeline().addLast(new NetworkHandler());
            }
        });
        channel = serverBootstrap.bind(networkConfiguration.getPort()).sync().channel();
        channel.closeFuture().syncUninterruptibly();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        eventLoopGroup.shutdownGracefully();
    }

Client main(String[]参数):

代码语言:javascript
复制
EventLoopGroup eventLoopGroup = epoll ? (EventLoopGroup) new EpollEventLoopGroup() : (EventLoopGroup) new NioEventLoopGroup();
    try {

        io.netty.bootstrap.Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup);
        bootstrap.channel(epoll ? EpollSocketChannel.class : NioSocketChannel.class);
        bootstrap.handler(new ChannelInitializer<Channel>() {
            protected void initChannel(Channel channel) throws Exception {
                channel.pipeline().addLast(new NetworkHandler());
            }
        });

        channel = bootstrap.connect(networkConfiguration.getMasterHostname(), networkConfiguration.getMasterPort()).sync().channel();
        packetCaller = new PacketCaller(channel);
        packetCaller.sendPacket(new PacketOutVerify(networkConfiguration.getWrapperName(), networkConfiguration.getKey()));
        channel.closeFuture().syncUninterruptibly();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        eventLoopGroup.shutdownGracefully();
    }

NetworkHandler中的channelActive:

代码语言:javascript
复制
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    ctx.pipeline().addLast(new PacketEncoder());
    ctx.pipeline().addLast(new PacketDecoder());
    this.waitingForRegistration.add(ctx.channel());
}

PacketDecoder

代码语言:javascript
复制
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> output) throws     Exception {
int id = byteBuf.readInt();
Class<? extends Packet> clazz = Wrapper.IN_PACKETS.get(id);
if (clazz == null) {
  throw new NullPointerException("Could not find packet by id " + id);
}

Packet packet = clazz.newInstance();
packet.read(byteBuf, ctx.channel());
}

PacketEncoder

代码语言:javascript
复制
public class PacketEncoder extends MessageToByteEncoder<Packet> {
@Override
protected void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf output) throws Exception   {
  int id = Wrapper.OUT_PACKETS.indexOf(packet.getClass());
  if(id == -1)
    throw new NullPointerException("Couldn't find packet of " + packet.getClass().getName());

  output.writeInt(id);
  packet.write(output, ctx.channel());
}
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-18 00:25:32

所以有多个问题。

首先,在PacketDecoder中,在尝试调用byteBuf.readInt()之前,您需要首先检查是否有4个字节可读。所以就像这样:

代码语言:javascript
复制
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf,      List<Object> output) throws Exception {
    if (byteBuf.readableBytes() < 4) {
        return;
    }
    int id = byteBuf.readInt();
    ...
}

其次,在Packet.read()方法中,您还需要确保有足够的可读字节,如果没有,请稍后重试

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67572527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档