如何解决netty自定义协议粘包分包问题

又一次发现公司同事用netty竟然都不处理粘包分包的问题,出了问题都不知道怎么回事,呵呵哒。sp厂商反馈数据已推送至我方提供的地址,但未收到我方的应答,正常推送了一次,又重试三次,都没有收到我方应答。

看了下代码,又跟踪了几条日志,发现sp数据确实有推送,只是我方解析失败。好多数据都是几条信息拼一起过来的,我方只按照头部长度解析了一条,导致许多数据都没有正常更新;还有部分数据是分两次过来的,本来应该放在一起解析一次,我方却解析了两次,自然失败了。

看了下报文约定,基本是这个样子,头部是总长度+固定的命令+序列号+报文数据。
在这里插入图片描述
这种自定义的,我一般使用 ByteToMessageDecoder来处理,要注意结合自定义报文约定,这里主要判定头长度和指定命令。

/**
* 基本长度(4+4+12) 4:总长度 4:命令标识 12:序列号
*/
private static final int BASE_LENGTH = 20;

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
   LOG.info("decode channelId:{}",ctx.channel().id().asShortText());
   if (in.readableBytes() <= BASE_LENGTH) {
       LOG.info("readables:{} channelId:{}",in.readableBytes(),ctx.channel().id().asShortText());
       return;
   }
   int length, command;
   while (true) {
       in.markReaderIndex();
       length = in.readInt();
       command = in.readInt();
       LOG.info("length:{},command:{}, channelId:{}",length,command,ctx.channel().id().asShortText());
       if (length > BASE_LENGTH && command == 0xF) {
           LOG.info("find command:{},channelId:{}",command,ctx.channel().id().asShortText());
           break;
       }
       in.resetReaderIndex();
       byte temp = in.readByte();
       LOG.info("skip a byte:{},channelId:{}",temp,ctx.channel().id().asShortText());

       if (in.readableBytes() <= BASE_LENGTH) {
           LOG.info("length:{} less than 20,channelId:{}",in.readableBytes(),ctx.channel().id().asShortText());
           return;
       }
   }
   in.resetReaderIndex();
   if (in.readableBytes() < length) {
       LOG.info("can read:{} less than length:{},channelId:{}",in.readableBytes(),length,ctx.channel().id().asShortText());
       return;
   }
   byte[] data = new byte[length];
   in.readBytes(data);
   LOG.info("success,length:{} data:{},channelId:{}",length,data,ctx.channel().id().asShortText());
   out.add(data);
}

比较简单,查看日志数据已经正常处理了,粘包数据会按报文约定分成多条数据处理,分包问题会等到数据到达指定长度时正确处理。netty用起来很简单,但数据还是要小心处理。

猜你喜欢

转载自blog.csdn.net/weixin_43275277/article/details/106737320