问题描述
有谁精通netty ,数据包解码是,不确定数据包大小,怎么能收到完整的数据包?
解决方案
我有个程序的包结构是这样的:1byte(包类型)+4byte(包体长度)+实际包体,于是写了下面的代码:public class ReceivingPacketHandler extends FrameDecoder { public static fianl int HEADER_SIZE=5;@Overrideprotected Object decode(ChannelHandlerContext ctx, Channel channel,ChannelBuffer buf) throws Exception {if (buf.readableBytes() < HEADER_SIZE) {// The header length field was not received yet - return null.return null;}buf.markReaderIndex();// Read protocol headerbuf.readByte();// Read the data length field.int length = buf.readInt();buf.resetReaderIndex();// Make sure if there's enough bytes in the buffer.int totalLength = length + HEADER_SIZE;if (buf.readableBytes() < totalLength) { //the whole packet was not received yet - return null.return null;}Packet recievedPacket = new Packet(size >= 0 ? size : bufSize);recievedPacket.clear();recievedPacket.readPacket(buf, totalLength);return recievedPacket;}}
解决方案二:
不确定包体的大小,可以采用header-content的方式,在header中标示真实包体的长度,类似http1.0协议中的content-length。具体可以参照netty中的objectencoder,首先长度位用4个字节占位待所有的内容写完再讲真实的长度写会长度占位
解决方案三:
我写过一系列的文章,对netty的源码研究过,http://asialee.iteye.com/blog/1769508,不知道对lz会不会有帮助,其中的DelimiterBasedFrameDecoder、LengthFieldBasedFrameDecoder、FrameDecoder希望对lz有所帮助。
解决方案四:
这个跟是不是用netty没有关系,牵涉到网络通信的地方都需要进行协议的制定。一般来说有如下几个点:1、结构定义:magicNumber+packageLength+自定义字段+消息内容+校验码2、粘包处理:解包的时候,先查找magicNum的位置,然后开始读取包长度,解析出有用的消息内容。如果接受的数据不足以刚好解出完整个数的数据包,把剩余的数据放到缓存,等下次接受数据之后拼接起来继续解包。把上面两个做好就可以了。
解决方案五:
这个和是否是netty没有关系,基于TCP的通信必须要有一定的规范,通常会在包头定义包的长度,你可以根据长度readFully读出整个包