我目前正在评估 Netty 以处理 Java 客户端与 C++ 服务器集成的套接字通信。消息传递协议具有以下结构 -
- (Type)(SubType)(Length)(MessageBody)和大小
- <4bytes><4bytes><4bytes><...> - 长度包括标题。
在 Netty api 之后,我将 LengthFieldBasedFrameDecoder 子类化以接收有效的完整数据包,然后根据接收到的类型对每个数据包进行解码。从我正在使用的文档中-
- 长度字段偏移 = 8
- 长度字段长度 = 4
- lengthAdjustment = -12(= HDR1 + LEN 的长度,负数)
- initialBytesToStrip = 0
它可以正常工作大约 5 分钟(我每 5 秒左右收到一条消息),然后解码事件包含一个比消息大小短得多的 ChannelBuffer。(我在崩溃前多次收到此消息)。然后我显然在我的内部解码代码中得到了一个 BufferUnderflowException 。难道我做错了什么?使用 LengthFieldBasedFrameDecoder 时,是否应该保证消息的缓冲区大小正确?
LengthFieldBasedFrameDecoder 类 -
public class CisPacketDecoder extends LengthFieldBasedFrameDecoder
{
public CisPacketDecoder(int maxFrameLength, int lengthFieldOffset,
int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) {
super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment,
initialBytesToStrip);
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
throws Exception
{
CisMessage message = null;
int type = buf.getInt(0); //Type is always first int
CisMessageType messageType = CisMessageType.fromIntToType(type);
if(messageType != null)
{
message = messageType.getObject();
if(message != null)
{
message.decode(buf.toByteBuffer());
}
else
{
System.out.println("Unable to create message for type " + type);
}
}
//mark the Channel buf as read by moving reader index
buf.readerIndex(buf.capacity());
return message;
}
}
并在这里实例化。
public class PmcPipelineFactory implements ChannelPipelineFactory
{
@Override
public ChannelPipeline getPipeline() throws Exception
{
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("encoder", new CisPacketEncoder());
pipeline.addLast("decoder", new CisPacketDecoder(1024, 8, 4, -12, 0));
pipeline.addLast("handler", new MsgClientHandler());
return pipeline;
}
}