【发布时间】:2014-03-04 12:14:08
【问题描述】:
我正在尝试使用 netty 4.0.10.Final 创建一个零拷贝应用程序。我有切片的问题。这是我的解码(有问题)方法:
@Override
protected void decode(ChannelHandlerContext chc, ByteBuf bb, List<Object> list) throws Exception {
int readableBytes = bb.readableBytes();
if (readableBytes < LENGTH_OF_HEADER) {
LOGGER.debug("skipping bb - too few data for header: " + readableBytes);
return;
}
int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER);
LOGGER.debug("length of actual message: {}", length);
if (readableBytes < length) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("skipping bb - too few data for msg: " +
readableBytes + " < " + length);
LOGGER.debug("bb: " + ByteBufUtils.byteBufToHexString(bb));
}
return;
}
LOGGER.debug("whole bb: " + ByteBufUtils.byteBufToHexString(bb));
LOGGER.debug("Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1));
ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length);
list.add(messageBuffer);
bb.skipBytes(length);
bb.retain();
LOGGER.debug("BB after slice: " + ByteBufUtils.byteBufToHexString(bb));
}
我的应用程序/网络也可以收到不完整的消息。
在接收到整个消息时,整个管道处理工作正常。我的管道从 ServerBootstrap -> ChannelInitializer -> ByteToMessageDecoder -> ByteToMessageDecoder -> MessageToMessageDecoder 开始。
当带有不完整消息的帧到达时,就会出现问题。
典型用例:
- 收到的帧比预期的消息短(消息在标头中有长度字段)
- 收到另一个完成不完整消息并携带另一个不完整消息的帧
- 创建完整消息的切片,不完整的消息等待其正文的其余部分(所有三个 .byteBufToHexString() 日志都是正确的)
- slice 被传递给下一个 ChannelHandler(也是 ByteToMessageDecoder)
- 在 sliced-bytebuf 内发送的数据已更改 - 使用不完整消息的字节而不是完整的消息字节
- 如果完整消息比不完整消息长(通常是这样),则使用完整消息字节的其余部分
示例(粗体 - 完整消息,斜体 - 不完整消息):
原始缓冲区 - 01 02 03 04 05 06 07 08 09 0A
切片缓冲区 - 01 02 03 04 05 06 07
下一个处理程序缓冲区 - 08 09 0A 04 05 06 07
这只发生在第一个“框架”消息和不完整的消息中。这两者之间的消息看起来不错。
与 .readSlice() 的结果相同。
复制数据有效(因为复制的 bytebuf 中的数据不共享)
有人看到错误吗?任何人都可以帮忙吗?
【问题讨论】:
标签: netty