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

硅谷探秘者 mqtt协议 463 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协议 431 (0xFF,0xFF,0xFF,0x7F)例如:可变头部和Payload(有效负载)的总节数是300个节。则的表示如下:1010110000000010关于的计算法可以参考
mqtt协议 353 /订阅(publish/subscribe)模式的”轻量级”通讯,该构建于TCP/IP上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代和有限的带宽,为连接远程设备提供
official 325 UpdaterequestHTTP包建立起连接,之后的通信全部使用websocket自己的,就和http没啥关系了。有兴趣的同学可以多了一下websocket报文的详细信息。Nettywebsoc
框架 2206 例:java类如下:publicclassQuestionnaireSubject{ privateIntegerid; privateStringname; publicIntegergetId
mqtt协议 1554 一次;QoS1,Atleastonce,至少一次;QoS2,Exactlyonce,确保只有一次;  QoS是消息的发送(Sender)和接受(Receiver)之间达成的一个:QoS0代表,S
数据结构和算法 718 /*** 链表节点类*@author硅谷探秘者(jia)*/classNode{ publicintdata; publicNodenext; publicNode(intdata){ this.data=data; } publicNode(Nodenext,intdata){ this.data=data; this.next=next; }}publicclassA3{ publics
official 328 统级别的底层(传输层)。很多的应用层的都是基于tcp或udp的,比如FTP(文件传送)、Telnet(远程登录)、DNS(域名)、SMTP(邮件传送),POP3
weblog 3499 是时间复杂确能降低到o(n2)。百科迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其各顶点的最短路径算法,决的是有权图中
归档
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
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础
目录
余生别太较劲,放过自己 才会幸福。