JT/T808消息体转义

前言

在网络传输过程中会存在粘包、半包等问题,在各个厂家做物联网产品的时候,大多会定义一种协议,协议里面包含了数据的包头、包尾以及校验位等字节,主要目的是为了在我们做物联网服务网关(接收物联网设备传输数据的系统)的时候方便对接收的数据进行校验以及处理粘包与半包问题。
为了防止消息体里面出现与包头包尾相同的字节出现,在物联网设备进行组包的时候一般会进行转移,就是将消息体中出现与包头包尾相同的字节按特定的规则转成其他字节。
比如:JT/T808协议,会将除包头包尾外整个消息体中出现的
0x7E——>0x7D 0x02
0x7D——>0x7D 0x01
所以我们在网关程序接收到设备的原始数据的时候,去掉包头、包尾之后需要进行反转义,然后将反转义后的数据在进行解析分析。
反转义:
0x7D 0x01——>0x7D
0x7D 0x02——>0x7E

C#实现

C#转义实现

        /// <summary>
        /// 息头、消息体、校验码中0x7E转义为0x7D 0x02,0x7D转义为0x7D 0x01
        /// </summary>
        /// <param name="inbytes"></param>
        /// <returns></returns>
        public byte[] escape(byte[] inbytes)
        {
            List<byte> list = new List<byte>();
            for (int i = 0; i < inbytes.Length; i++)
            {
                byte b = inbytes[i];
                if (b == 0x7e)
                {
                    list.Add(0x7d);
                    list.Add(0x02);
                }
                else if (b == 0x7d)
                {
                    list.Add(0x7d);
                    list.Add(0x01);
                }
                else
                {
                    list.Add(b);
                }
            }
            return list.ToArray();
        }

C#反转义实现

        /// <summary>
        /// 消息头、消息体、校验码中0x7D 0x02反转义为0x7E,0x7D 0x01反转义为0x7D
        /// </summary>
        /// <param name="inbytes"></param>
        /// <returns></returns>
        public byte[] unescape(byte[] inbytes)
        {
            List<byte> list = new List<byte>();
            int i = 0;
            int bodyLength = inbytes.Length;
            if (i < bodyLength)
            {
                byte firstByte = inbytes[i];
                if (firstByte == 0x7d)
                {
                    byte nextByte = inbytes[i + 1];
                    if (nextByte == 0x01)
                    {
                        list.Add(0x7d);
                    }
                    else if (nextByte == 0x02)
                    {
                        list.Add(0x7e);
                    }
                    else
                    {
                        list.Add(firstByte);
                        list.Add(nextByte);
                    }
                    i += 2;
                }
                else
                {
                    list.Add(firstByte);
                    i++;
                }
            }
            return list.ToArray();
        }

Java实现

基于Netty框架

JAVA 转义实现

    /**
     * 消息头、消息体、校验码中0x7E转义为0x7D 0x02,0x7D转义为0x7D 0x01
     *
     * @param out
     * @param bodyBuf
     */
    public static void escape(ByteBuf out, ByteBuf bodyBuf) {
        while (bodyBuf.readableBytes() > 0) {
            int b = bodyBuf.readUnsignedByte();
            if (b == 0x7E) {
                out.writeShort(0x7D02);
            } else if (b == 0x7D) {
                out.writeShort(0x7D01);
            } else {
                out.writeByte(b);
            }
        }
    }

JAVA 反转义实现

    /**
     * 消息头、消息体、校验码中0x7D 0x02反转义为0x7E,0x7D 0x01反转义为0x7D
     *
     * @param in
     * @param frame
     * @param bodyLen
     */
    public static void unescape(ByteBuf in, ByteBuf frame, int bodyLen) {
        int i = 0;
        while (i < bodyLen) {
            int b = in.readUnsignedByte();
            if (b == 0x7D) {
                int nextByte = in.readUnsignedByte();
                if (nextByte == 0x01) {
                    frame.writeByte(0x7D);
                } else if (nextByte == 0x02) {
                    frame.writeByte(0x7E);
                } else {
                    //异常数据
                    frame.writeByte(b);
                    frame.writeByte(nextByte);
                }
                i += 2;
            } else {
                frame.writeByte(b);
                i++;
            }
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大鱼>

一分也是爱

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

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

打赏作者

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

抵扣说明:

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

余额充值