Netty:奇怪的 IndexOutOfBoundsException:readerIndex + 长度超过 writerIndex

2024-05-03

我目前正在通过 netty 发送不同的数据包,并且经常遇到这样的异常收到它们时:

java.lang.IndexOutOfBoundsException: readerIndex(39) + length(32) exceeds writerIndex(64): UnpooledUnsafeDirectByteBuf(ridx: 39, widx: 64, cap: 2048)
at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1166)
at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:655) 
at <snip>.PacketDataHolder.readString(PacketDataHolder.java:79)

...... 或者

java.lang.IndexOutOfBoundsException: readerIndex(0) + length(1) exceeds writerIndex(0): UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 2048)
at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1166)
at io.netty.buffer.AbstractByteBuf.readByte(AbstractByteBuf.java:570) ......

这是我发送数据包的方式:

public void sendPacket(Packet packet) {
    PacketDataHolder packetDataHolder = new PacketDataHolder(); //I'm creating a packetDataHolder, code is below
    packetDataHolder.writeHeader(packet); //Then i'm adding the packet ID as a header
    packet.writeData(packetDataHolder); //Then I'm writing the data of the packet (String for example)
    socketChannel.writeAndFlush(packetDataHolder.getByteBuf()); //Then I'm sending the packet
}

以及我如何接收和阅读它们:

protected void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
    PacketDataHolder packetDataHolder = new PacketDataHolder(byteBuf); //First I'm creating a PacketDataHolder containing the bytebuf
    Packet packet = PacketParser.parsePacket(packetDataHolder); //Then I'm parsing the header I wrote (The packet id)

这是相关代码:

(PacketDataHolder 类) 公共同步无效writeHeader(数据包数据包){ this.writeByte(packet.getId()); }

public synchronized byte readHeader() {
    return this.readByte();
}
public synchronized void writeByte(int value) {
    this.byteBuf.writeByte(value);
}

public synchronized byte readByte() {
    return this.byteBuf.readByte();
}
public synchronized void writeString(String value) {
    if(value == null)
        value = "An error occurred while displaying this message";
    byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
    if (bytes.length > 32767)
        throw new EncoderException("String too big (was " + value.length()
                + " bytes encoded, max 32767)");
    else {
        writeVarInt(bytes.length);
        byteBuf.writeBytes(bytes);
    }
}

public synchronized String readString() {
    int length = readVarInt();
    if (length < 0)
        throw new DecoderException(
                "The received encoded string buffer length is less than zero! Weird string!");
    return new String(byteBuf.readBytes(length).array(),
            StandardCharsets.UTF_8);
}

我描述的第一个错误总是发生在 writeString 方法中,所以我认为它以任何方式与此相关。 我认为这主要是在发送很长的字符串时发生的,但我不确定。

如果您需要更多示例代码,请随时询问! 我希望你可以帮助我, 燃烧器


您的代码假设您的通信通道正在处理帧。也就是说,它期望当您发送 1024 字节时,接收处理程序将收到正好 1024 字节的 bytebuf。据我所知,您的代码直接写入 TCP,这是一种基于流的协议,不能以这种方式工作。如果写入 1024 字节,对等方将收到所有 1024 字节,但字节可能会分段到达 - 例如两次调用channelRead0(第一个调用 300,第二个调用 724)。

幸运的是,Netty 包含几个开箱即用的帧编解码器来为您处理这个问题。请参阅以下位置的示例http://netty.io/4.0/xref/io/netty/example/worldclock/WorldClockServerInitializer.html http://netty.io/4.0/xref/io/netty/example/worldclock/WorldClockServerInitializer.html

它展示了如何使用 ProtobufVarint32FrameDecoder(确保管道中的下一个处理程序一次始终接收一帧字节)和 ProtobufVarint32LengthFieldPrepender(负责将帧长度标头添加到所有传出消息中)配置服务器通道

我建议您更改代码以将这些(或类似的帧编解码器)插入到您的管道中。然后将您的应用程序代码修改为not调用 readVarInt 和 writeVarInt 因为编解码器会为您处理这个问题。接收到的 ByteBuf 的大小将始终与发送的 ByteBuf 的大小匹配,因为解码器负责聚合所有片段。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Netty:奇怪的 IndexOutOfBoundsException:readerIndex + 长度超过 writerIndex 的相关文章

  • 使用netty高速发送消息时出现OOM异常

    我用netty编写了一个客户端 以便以高速率发送消息 通过 jConsole 我看到 老一代 正在增加 最后它抛出 java lang OutOfMemoryError 超出 GC 开销限制 是否有一些方法或配置可以避免此异常 以下是我的测
  • 分析 Netty 性能

    我正在编写一个 Netty 应用程序 该应用程序在 64 位八核 Linux 机器上运行 Netty 应用程序是一个简单的路由器 它接受请求 传入管道 从请求中读取一些元数据并将数据转发到远程服务 传出管道 该远程服务将向传出管道返回一个或
  • Netty Channel.write 线程安全吗?

    我有一个 Netty 应用程序 我希望有多个线程写入通道 我只是想知道 Channel write 是否线程安全 从代码中可以看出 ChannelOutboundBuffer addMessage 方法本身不是线程安全的 然而 写入通道是
  • 在处理程序中组装 Netty 消息

    我正在为我的项目制作 Netty 原型 我正在尝试在 Netty 之上实现一个简单的面向文本 字符串的协议 在我的管道中 我使用以下内容 public class TextProtocolPipelineFactory implements
  • 严重:泄漏:在垃圾收集之前未调用 ByteBuf.release()。内蒂

    我已经创建了一些游戏服务器 并且刚刚与大约 10 个伙伴进行了测试 一切都很顺利 我们玩了大约 10 分钟 在游戏的某个时刻 游戏服务器停止为客户端提供服务 断开了每个人的连接 而且我连接到运行游戏的 VPS 的 SSH 也断开了连接 我不
  • 每个 UDP 数据报的 Netty 不同管道

    我们有一个已经在 TCP IP 中实现的服务器 但现在我们要求该协议也支持 UDP 发送的每个 UDP 数据报都包含我需要解码的所有内容 因此这是一个非常简单的回复和响应系统 数据报中的数据由换行符分隔 服务器启动时的引导代码如下所示 SE
  • ChannelOption.SO_BACKLOG 的作用是什么?

    option ChannelOption SO BACKLOG 100 Netty 4 升级文档中显示 你能解释一下它的作用吗 Thanks 它是一个传递的套接字选项 用于确定排队的连接数 http docs oracle com java
  • 为什么JDK NIO使用这么多anon_inode文件描述符?

    我正在使用 Sun 的 JDK 1 6 0 26 和 NIO 带有 Netty 在 lsof 中我看到数百个文件描述符anon inode lsof np 11225 fgrep w anon inode java 11225 nobody
  • Netty 4. ByteToMessageCodec之后的并行处理

    If a NioEventLoopGroup被用作workerGroup 之后的消息ByteToMessageDecoder处理程序 对于单个连接 通过以下处理程序以顺序 单线程 方式处理NioEventLoop 是否有可能让它们在之后由另
  • netty ChannelInboundHandlerAdapter 将帧裁剪为 ~1500 字节

    我已经实现了一个服务器应用程序 它使用 netty 框架通过 ChannelInblundHandlerAdapter 读取传入的字节 如标题所示 我的问题是 我不定期地从客户端获取内容 我认为这些内容在 1 500 字节后被剪切 例如 在
  • 内蒂不写

    当尝试使用 netty 写入时 写入的数据永远不会在远程端结束 这已通过 Wireshark 确认 我努力了 Directly using writeAndFlush channel writeAndFlush new Packet Man
  • Netty websocket客户端闲置5分钟后不从服务器读取新帧

    我在服务器端和客户端都使用 Netty 来建立和控制 websocket 连接 我在服务器端有一个空闲状态处理程序 http netty io 4 1 api io netty handler timeout IdleStateHandle
  • StringIndexOutOfBoundsException 字符串索引超出范围错误

    当我在输入整数后输入字符串 s 时 出现此错误 Exception in thread main java lang StringIndexOutOfBoundsException String index out of range 0 a
  • netty DefaultChannelPipeline 异常捕获

    不幸的是 我不明白 netty 服务器的输出 BUILD SUCCESSFUL Total time 3 seconds Jul 27 2014 2 04 44 AM io netty handler logging LoggingHand
  • Netty 处理程序未调用

    我正在尝试使用简单的服务器客户端应用程序进入 Netty 代码见下文 我正在努力解决两个问题 ConfigServerHandler 分别ConfigClientHandler 被正确调用 但是 FeedbackServerHandler
  • Java 互操作——Netty + Clojure

    我正在尝试通过 clojure 使用 netty 我可以启动服务器 但是它无法初始化接受的套接字 下面分别是错误消息和代码 有谁知道什么是 或可能是错误的 我相信问题在于 Channels pipeline server handler T
  • netty 4.x.x 中的 UDP 广播

    我们需要使用 Netty 4 0 0 二进制文件通过 UDP 通道广播对象 Pojo 在 Netty 4 0 0 中 它允许我们仅使用 DatagramPacket 类来发送 UDP 数据包 此类仅接受 ByteBuf 作为参数 还有其他方
  • 不同的 Netty 版本及其用途

    我现在使用Netty有一段时间了 但永远无法解决这个问题 一个人可以下载四个不同的版本 其中三个正在积极开发中 3 x 4 0 x 4 1 x 5 x 据我了解 3 x 适用于 JRE 1 5 而 JRE 的其他所有版本都高于此版本 我使用
  • Netty:奇怪的 IndexOutOfBoundsException:readerIndex + 长度超过 writerIndex

    我目前正在通过 netty 发送不同的数据包 并且经常遇到这样的异常收到它们时 java lang IndexOutOfBoundsException readerIndex 39 length 32 exceeds writerIndex
  • Spring WebFlux Netty SSL 与自签名证书错误

    我正在尝试使用服务器端的自签名证书通过本地主机中的 https 访问在 Netty 上运行的 Spring Boot 应用程序 My application properties看起来像这样 server ssl enabled true

随机推荐