Netty接收被拆分过的包

Netty接收被拆分过的包

问题:

在使用Netty进行自定义协议(发送数据前在数据前加上4字节的长度)TCP客户端操作,,连接到服务器后,接收到服务器返回的数据超过了最大缓冲区进行了拆包,导致在Decoder内接受到的数据不完整,需要分次进行读取,然后读取完成后再往inbound内推。

自定义协议:

在业务数据前加上4字节的长度数据,如果业务数据长度是10字节,则最后接受到的数据应该是14字节

处理逻辑是这样的:

在Decoder里,对接收到的数据进行完整性判断。

  • 自定义一个局部变量dataLen代表业务数据的长度,初始化为-1
  • 有数据进入,判断dataLen是否是-1,如果是,则是第一批数据进入,如果不是,则是追加的数据
  • 通过 in.readableBytes() 来判断当前数据量是否与业务的数据总量一直,如果不一致,则调用in.resetReaderIndex()重置读取index,下次继续从0开始读。
  • 当总的数据量与业务上的数据量一致,则通过list.add()方法,往上抛出数据,并设置dataLen=-1保证下次的判断。

直接上解决代码:

public class Decoder extends ByteToMessageDecoder {
    static Logger logger = LoggerFactory.getLogger(Decoder.class);

    //根据自定义的协议,得到前4个字节的数据来计算总的数据长度
    int dataLen = -1;

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List list) throws Exception {

        byte[] dataBytes = new byte[in.readableBytes()];
        in.readBytes(dataBytes);
        logger.info("接收到tcp数据");
        if (dataLen == -1) {
            //取4个字节的数据进行数据的长度计算
            byte[] lenBuff = AppUtils.subByte(dataBytes,0,4);
            dataLen = AppUtils.bytesToIntLittle(lenBuff,0);
            logger.info("数据长度为:" + (dataLen + 4));
            if (dataBytes.length == dataLen + 4) {
                logger.info("数据完整,释放");

                list.add(dataBytes);
                dataLen = -1;
            }else {
                logger.info("数据不足,继续等待接受,总长度:"+(dataLen + 4)+",当前长度:" + dataBytes.length);
                //这一步很重要,如果前面已经read过了数据,则buf的读取索引会相应的移动,因为当前数据并不完整,所以重置所以为0,下次继续从0开始读
                in.resetReaderIndex();
            }

        }else {
            if (dataBytes.length == dataLen + 4) {
                logger.info("数据完整,释放");
                list.add(dataBytes);
                dataLen = -1;
            }else {
                logger.info("数据不足,继续等待接受,总长度:"+(dataLen + 4)+",当前长度:" + dataBytes.length);
                in.resetReaderIndex();
            }
        }

    }
}

 

                            
                        
                    
                    
                    

你可能感兴趣的:(Netty接收被拆分过的包)