mqtt协议剩余长度字段编解码实现方案(java)

硅谷探秘者 Md mqtt协议 1240 0 0

mqtt协议报文解析,参考:http://www.jiajiajia.club/blog/artical/kdv1qvpfgbh4/514

  根据mqtt协议的定义,剩余长度字段是可变的,最少用一个字节最多四个字节来表示,而且每个字节的最高位不表示有效数据,用来表示有没有下一个字节。所以每个字节能表示的数据的最大值是128,所以剩余长度字段可表示的最大值是128 * 128 * 128 * 128,则理论上能表示数据包大小的最大值是256M。

  对剩余长度字段的编解码,可理解为128进制的运算。如果低位字节满128,则向高位字节进1。那么进位系数就是128。

  下面是用一段代码描述对剩余长度字段的计算方法(java实现)。


    public static void main(String[] args) throws Exception{
        int length = 300;
        final byte[] encode = encode(length);
        System.out.println("编码:"+length);
        for (byte b : encode) {
            System.out.println(getBinaryStrFromByte(b));
        }
        System.out.println();
        System.out.println("解码:"+decode(encode));
    }

    /**
     * mqtt固定报文头剩余长度的编码方案
     * @param x 字节大小
     * @return 编码结果
     */
    public static byte[] encode(int x){
        byte encodeBytes[] = new byte[x < 2<<6 ? 1 : x < 2<<13 ? 2 : x < 2<<20 ? 3 : 4];
        int encodeByte;
        int i=0;
        do{
            // 128进制,满128进1
            encodeByte = x % 128;
            x = x / 128;
            if( x > 0 )
                // encodeByte | 128 保证最高位必须是1
                encodeByte = encodeByte | 128;
            encodeBytes[i]=(byte)encodeByte;
            i+=1;
        }while (x>0);
        return encodeBytes;
    }

    /**
     * mqtt固定报文头剩余长度的编码方案
     * @param bytes 编码后的字节数据
     * @return 解码后的字节剩余长度
     */
    public static int decode(byte[] bytes){
        // multiplier 进位系数,第一个字节的进位系数是1,第二个字节的进位系数是128,
        // 第三个字节的进位系数是 128 * 128,第四个字节的进位系数是 128 * 128 * 128
        int multiplier = 1;
        int value = 0;
        int i=0;
        byte encodedByte;
        do {
            encodedByte = bytes[i];
            // encodedByte & 127 去掉最高位的1,因为最高位不表示数据
            value += (encodedByte & 127) * multiplier;
            multiplier *= 128;
            if (multiplier > 128 * 128 * 128)
                return -1;
            i+=1;
            // (encodedByte & 128) != 0 代表encodedByte该字节的最高位是1,
            // 所以根据mqtt对剩余字段长度的定义应该还有下一个字节。
        }while ((encodedByte & 128) != 0);
        return value;
    }

    /**
     * 字节转二进制字符串
     * @param encodeByte byte
     * @return 二进制字符串
     */
    public static String getBinaryStrFromByte(byte encodeByte){
        StringBuilder result = new StringBuilder();
        byte a = encodeByte; ;
        for (int i = 0; i < 8; i++){
            int i1 = a % 2;
            result.append(i1>0?i1:-i1);
            a=(byte)(a>>1);
        }
        return result.reverse().toString();
    }

评论区
请写下您的评论...
暂无评论...
猜你喜欢
mqtt协议 1578 (0xFF,0xFF,0xFF,0x7F)例如:可变头部和Payload(有效负载)的总节数是300个节。则的表示如下:1010110000000010关于的计算法可以参考
mqtt协议 1317 /订阅(publish/subscribe)模式的”轻量级”通讯,该构建于TCP/IP上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代和有限的带宽,为连接远程设备提供
mqtt协议 582 pom依赖dependencygroupIdorg.eclipse.paho/groupIdartifactIdorg.eclipse.paho.client.mqttv3/artifactIdversion1.2.0/version/dependency发布端importorg.eclipse.paho.client.mqttv3.MqttClient;importorg.eclipse.pah
official 784 UpdaterequestHTTP包建立起连接,之后的通信全部使用websocket自己的,就和http没啥关系了。有兴趣的同学可以多了一下websocket报文的详细信息。Nettywebsoc
框架 3055 例:java类如下:publicclassQuestionnaireSubject{ privateIntegerid; privateStringname; publicIntegergetId
mqtt协议 3673 一次;QoS1,Atleastonce,至少一次;QoS2,Exactlyonce,确保只有一次;  QoS是消息的发送(Sender)和接受(Receiver)之间达成的一个:QoS0代表,S
数据结构和算法 1172 /*** 链表节点类*@author硅谷探秘者(jia)*/classNode{ publicintdata; publicNodenext; publicNode(intdata){ this.data=data; } publicNode(Nodenext,intdata){ this.data=data; this.next=next; }}publicclassA3{ publics
keepalived,nginx,linux 1247 LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以高可用的VRRP(VirtualRouterRedundancyProtocol,虚拟路由器冗)功
归档
2018-11  12 2018-12  33 2019-01  28 2019-02  28 2019-03  32 2019-04  27 2019-05  33 2019-06  6 2019-07  12 2019-08  12 2019-09  21 2019-10  8 2019-11  15 2019-12  25 2020-01  9 2020-02  5 2020-03  16 2020-04  4 2020-06  1 2020-07  7 2020-08  13 2020-09  9 2020-10  5 2020-12  3 2021-01  1 2021-02  5 2021-03  7 2021-04  4 2021-05  4 2021-06  1 2021-07  7 2021-08  2 2021-09  8 2021-10  9 2021-11  16 2021-12  14 2022-01  7 2022-05  1 2022-08  3 2022-09  2 2022-10  2 2022-12  5 2023-01  3 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。