从LengthFieldBasedFrameDecoder返回的缓冲区太小

编程入门 行业动态 更新时间:2024-10-28 11:19:56
本文介绍了从LengthFieldBasedFrameDecoder返回的缓冲区太小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我目前正在评估Netty,以处理Java客户端与C ++服务器集成的套接字通信.消息传递协议具有以下结构-

I am currently evaluating Netty to handle socket comms for a Java client to integrate with a C++ server. The messaging protocol has the following structure -

  • (类型)(子类型)(长度)(MessageBody)大小
  • < 4bytes>< 4bytes>< 4bytes>< ...> -长度包括标题.
  • (Type)(SubType)(Length)(MessageBody) with size
  • <4bytes><4bytes><4bytes><...> - The Length includes the header.

在Netty api I子类LengthFieldBasedFrameDecoder之后,它接收有效的完整数据包,然后根据接收的类型对每个数据包进行解码.从我正在使用的文档中-

Following the Netty api I subclass LengthFieldBasedFrameDecoder to receive a valid full packet and then decode each packet depending on the type received. From docs I'm using -

  • lengthFieldOffset = 8
  • lengthFieldLength = 4
  • lengthAdjustment = -12(= HDR1 + LEN的长度,负数)
  • initialBytesToStrip = 0

它可以正常工作约5分钟(我每5秒左右收到一条消息),然后解码事件包含一个ChannelBuffer,该ChannelBuffer短于消息的大小. (崩溃之前,我已经多次收到此消息).然后,我显然在我的内部解码代码中得到了BufferUnderflowException.难道我做错了什么?使用LengthFieldBasedFrameDecoder时,是否应该保证消息的缓冲区大小正确?

It works fine for about 5 minutes (I'm getting one message every 5 seconds or so) and then the decode event contains a ChannelBuffer that is much shorter than the size of the message. (I have received this message multiple times before the crash). I then obviously get an BufferUnderflowException in my internal decode code. Am I doing something wrong? Should I be guaranteed the correct sized buffer for the message when using LengthFieldBasedFrameDecoder?

LengthFieldBasedFrameDecoder类-

LengthFieldBasedFrameDecoder class -

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; } }

推荐答案

您需要调用super.decode(..)并在您的encode(..)方法中对返回的ChannelBuffer进行操作.

You need to call super.decode(..) and operate on the returned ChannelBuffer in your decode(..) method.

所以会是这样;

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 { // THIS IS IMPORTANT!!!!! ChannelBuffer decoded = (ChannelBuffer) super.decode(ctx, channel, buf); if (decoded == null) { return null; } // NOW ONLY OPERATE ON decoded CisMessage message = null; int type = decoded.getInt(0); //Type is always first int CisMessageType messageType = CisMessageType.fromIntToType(type); if(messageType != null) { message = messageType.getObject(); if(message != null) { message.decode(decoded.toByteBuffer()); } else { System.out.println("Unable to create message for type " + type); } } return message; } }

请务必检查大写注释.

更多推荐

从LengthFieldBasedFrameDecoder返回的缓冲区太小

本文发布于:2023-06-05 01:22:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/508954.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓冲区   太小   LengthFieldBasedFrameDecoder

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!