gpt4 book ai didi

java - 如何让我的 bytebuf 发送我的整个消息 Netty

转载 作者:行者123 更新时间:2023-12-01 18:33:36 25 4
gpt4 key购买 nike

我每个人。

我问你是因为我的Netty解码器中的ByteBuf有问题。

我想解码通过服务器到达的消息,但 ByteBuf 无法像我希望的那样工作。

问题是 ByteBuf 没有获取消息的所有字节。

我解释一下,我有一条消息,长度为 1221 字节(这是一个示例),但缓冲区大小只有 64 字节。

当我尝试读取具有我的长度的缓冲区时,我遇到这样的错误:

io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(117) + length(101) exceeds writerIndex(192): PooledUnsafeDirectByteBuf(ridx: 117, widx: 192, cap: 192)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:470) ~[netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:697) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:632) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:549) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:511) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.37.Final.jar:4.1.37.Final]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181]

我认为 Netty 没有时间阅读所有内容并仅发送部分消息,但我现在不知道是否可以配置 Netty,因为他必须等到消息完整到达。

如果有人能帮助我,我很感激

为了获得大多数帮助,我给你解码器的代码

    int length = buffer.readInt();
int messageType = buffer.readInt();


Supplier<AbstractMessage> supplier = SUPPLIERS.get(messageType);
if (supplier == null) {
LOGGER.debug("This message type isn't supported: {}", messageType);
} else {
ByteBuf data = buffer.readBytes(length);
if (messageType != 6) {
AbstractMessage message = supplier.get();
message.read(data, version);
list.add(message);
LOGGER.debug("{}", message);
}
}
}

}

消息格式如下:消息长度(4 个字节)(int)4 个字节的消息类型 (int)n 字节数据(MessageLength 大小)

我给你我用于解释的文档Here .

最佳答案

您需要通过扩展 ByteToMessageDecoder 和缓冲区来编写自己的解码器,直到收到所有内容。由于这是 TCP,您可能会以碎片方式接收字节,因此您需要自己再次组装它。

这样的事情应该有效:

class MyDecoder extends ByteToMessageDecoder {

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) {
if (input.readableBytes() < 4) {
// we need to have at least 4 bytes to read to be able to get the message length
return;
}
int length = input.getInt(input.readerIndex());
if (input.readableBytes() < 8 + length) {
// ensure we have enough data so we can also read the message type and the whole message body
return;
}
// skip the length now
input.skipBytes(4);

int messageType = input.readInt();

Supplier<AbstractMessage> supplier = SUPPLIERS.get(messageType);
if (supplier == null) {
LOGGER.debug("This message type isn't supported: {}", messageType);
input.skip(length);
} else {
if (messageType != 6) {
ByteBuf data = buffer.readSlice(length);
AbstractMessage message = supplier.get();
message.read(data, version);
list.add(message);
LOGGER.debug("{}", message);
}
}
}
}

关于java - 如何让我的 bytebuf 发送我的整个消息 Netty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60111841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com