如何解决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用起来很简单,但数据还是要小心处理。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小麦

一起学习共同进步

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值