私は現在、JavaクライアントがC++サーバーと統合するためのソケット通信を処理するためにNettyを評価しています。メッセージングプロトコルの構造は次のとおりです-
- (Type)(SubType)(Length)(MessageBody) with size
- <4bytes> <4bytes><4bytes><...> -長さにはヘッダーが含まれます。
Netty api Iに続いて、LengthFieldBasedFrameDecoderをサブクラス化して、有効な完全なパケットを受信し、受信したタイプに応じて各パケットをデコードします。私が使用しているドキュメントから-
- lengthFieldOffset = 8
- lengthFieldLength = 4
- lengthAdjustment = -12(= HDR1 + LENの長さ、負)
- initialBytesToStrip = 0
約5分間は正常に動作し(5秒ごとに1つのメッセージが表示されます)、デコードイベントにはメッセージのサイズよりもはるかに短い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;
}
}