Netty中JT808粘包和拆包

       开发部标JT808GPS平台,使用java语言开发网关程序,目前普遍使用Netty。众所周知,TPC编程要解决粘包和拆包问题。现提供一种解决方案如下: 

public class ProtocolDecoder extends ByteToMessageDecoder {

    private Logger logger = Logger.getLogger(ProtocolDecoder.class);

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in == null) {
            return;
        }
        in.markReaderIndex();
        ByteBuf byteBuf = in.asReadOnly();
        byteBuf.markReaderIndex();
        while (in.isReadable()) {
            in.markReaderIndex();
            int packetBeginIndex = in.readerIndex();
            byte tag = in.readByte();
            // 搜索包的开始位置
            // 处理黏包和拆包
            if(tag==0x7E){
                if(!in.isReadable()){
                    in.resetReaderIndex();
                    return;
                }
                else{
                    tag = in.readByte();
                    // 防止是两个0x7E,取后面的为包的开始位置
                    // 寻找包的结束
                    while (tag != 0x7E) {
                        if (in.isReadable() == false) {
                            in.resetReaderIndex(); // 没有找到结束包,等待下一次包
                            // logger.error("半包:"+Tools.toHexString(data));
                            return;
                        }
                        tag = in.readByte();
                    }
                    int pos = in.readerIndex();
                    int packetLength = pos - packetBeginIndex;
                    if (packetLength > 2) {
                        byte[] tmp = new byte[packetLength];
                        in.resetReaderIndex();
                        in.readBytes(tmp);
                        //logger.error("收到数据 = " +  Tools.toHexString(tmp));
                        T808Message message = new T808Message();
                        message.readFromBytes(tmp);
                        out.add(message); // 触发接收Message的事件
                        // return message;
                    } else {
                        // 说明是两个0x7E
                        logger.error("收到2个7E,Index:" + in.readerIndex() + " 长度 = " + packetLength + " 末尾数据 = " +  Tools.toHexString(new byte[]{tag}));
                        in.resetReaderIndex();
                        in.readByte(); // 两个7E说明前面是包尾,后面是包头
                    }
                }
            }else if (in.isReadable() && byteBuf.isReadable()){
                byte[] bytes = new byte[byteBuf.readableBytes()];
                byteBuf.readBytes(bytes);
                logger.error( "(" + ctx.channel().id().asLongText() + "," + ctx.channel().remoteAddress() + ") Index:" + in.readerIndex() + " 存在非法数据:" + Tools.toHexString(bytes));
            }
        }
        return;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值