gpt4 book ai didi

java - 当缓冲区大小小于帧大小时,LengthFieldBasedFrameDecoder 无法正确解析

转载 作者:行者123 更新时间:2023-11-30 07:54:53 24 4
gpt4 key购买 nike

我正在使用基于帧的解码器对 netty 管道进行单元测试。如果我使用小于最大帧的缓冲区大小,那么看起来帧是不正确的。我正在测试一个包含两条消息的文件。长度字段是第二个工作,包括整个消息的长度,包括长度字段和它之前的工作。

 new LengthFieldBasedFrameDecoder(65536, 4, 4, -8, 0)

我正在读取一个具有不同 block 大小的文件。第一条消息的大小是 348 字节,第二条是 456 字节。如果使用 512、3456 或更大的 block 大小,则两条消息都被读取并正确地构造到下一个处理程序,出于诊断目的,该处理程序将打印出它接收到的缓冲区内容的十六进制字符串。如果使用较小的 block 大小,则会发生帧错误。用于读写文件的代码如下所示。

public class NCCTBinAToCSV {
private static String inputFileName = "/tmp/combined.bin";
private static final int BLOCKSIZE = 456;
public static void main(String[] args) throws Exception {
byte[] bytes = new byte[BLOCKSIZE];
EmbeddedChannel channel = new EmbeddedChannel(
new LengthFieldBasedFrameDecoder(65536, 4, 4, -8, 0),
new NCCTMessageDecoder(),
new StringOutputHandler());
FileInputStream fis = new FileInputStream(new File(inputFileName));
int bytesRead = 0;
while ((bytesRead = fis.read(bytes)) != -1) {
ByteBuf buf = Unpooled.wrappedBuffer(bytes, 0, bytesRead);
channel.writeInbound(buf);
}
channel.flush();
}
}

block 大小为 356 字节的成功运行的输出如下所示(为简洁起见,消息正文被截断

LOG:DEBUG 2017-04-24 04:19:24,675[main](netty.NCCTMessageDecoder) -  com.ticomgeo.mtr.ncct.netty.NCCTMessageDecoder.decode(NCCTMessageDecoder.java:21) ]received 348 bytes

Frame Start========================================

(byte) 0xbb, (byte) 0x55, (byte) 0x05, (byte) 0x16,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x5c,
(byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x02,
(byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x50, (byte) 0x3a, (byte) 0xc9, (byte) 0x17,

....
Frame End========================================

Frame Start========================================

(byte) 0xbb, (byte) 0x55, (byte) 0x05, (byte) 0x1c,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0xc8,
(byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x02,
(byte) 0x05, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x01,

如果我将 block 大小更改为 256,错误的字节似乎被读取为长度字段。

Exception in thread "main" io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 65536: 4294967040 - discarded
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:499)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:477)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:403)

最佳答案

长话短说;你的问题是因为netty重用了传入的bytebuf,然后你覆盖了内容。

LengthFieldBasedFrameDecoder 是通过继承来重用传入的ByteBuf,因为当你可以重用它时让对象通过垃圾回收衰减是没有用的,因为它的引用计数是 1. 然而,问题来自这样一个事实,即您正在更改传入的 bytebuf 的内部结构,因此会动态更改框架。你应该使用 copiedBuffer,而不是制作一个 wrappedBuffer,它使用你传入的变量作为存储,因为它正确地制作了它的副本,所以 LengthFieldBasedFrameDecoder 可以用它自由地做事。

关于java - 当缓冲区大小小于帧大小时,LengthFieldBasedFrameDecoder 无法正确解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43592095/

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