MQTT 单片机端讲解

     有空了和大家分享一下,如何从头架构一个高效mqtt并行客户端,基于传统GPRS等较差网络环境和网关等网络环境好的情景(当然仔细讲解mqtt的基本函数使很有必要的)。---这会正忙着搬砖

MQTt协议 第一个字节用来表示报表类型

 

接下来第二个字节开始是剩余长度

表示长度,最多用4个字节,变长,每个字节的高位表示后面是否还有表示长度的字节,也就是说每个字节可以表示128个字节的长度

本篇标注  标识符适用于qos大于0的情况。

其他细节  

https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/02-ControlPacketFormat.html

本文要点

/**
 * Decodes the message length according to the MQTT algorithm
 * @param getcharfn pointer to function to read the next character from the data source
 * @param value the decoded length returned
 * @return the number of bytes read from the socket
 */
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)
{
    unsigned char c;
    int multiplier = 1;
    int len = 0;
#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4 //读取更多数据

    FUNC_ENTRY;
    *value = 0;
    do
    {
        int rc = MQTTPACKET_READ_ERROR;

        if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
        {
            rc = MQTTPACKET_READ_ERROR;    /* bad data */
            goto exit;
        }
//        rc = (*getcharfn)(&c, 1);
//        if (rc != 1)
//            goto exit;
        *value += (c & 127) * multiplier;
        multiplier *= 128;
    } while ((c & 128) != 0);
exit:
    FUNC_EXIT_RC(len);
    return len;
}

该代码作用提取报文可变字节长度 ,最多提取4个字节

/**
 * Encodes the message length according to the MQTT algorithm
 * @param buf the buffer into which the encoded data is written
 * @param length the length to be encoded
 * @return the number of bytes written to buffer
 */
int MQTTPacket_encode(unsigned char* buf, int length)
{
    int rc = 0;

    FUNC_ENTRY;
    do
    {
        char d = length % 128;
        length /= 128;
        /* if there are more digits to encode, set the top bit of this digit */
        if (length > 0)
            d |= 0x80;
        buf[rc++] = d;
    } while (length > 0);
    FUNC_EXIT_RC(rc);
    return rc;
}

该代码作用,重新编码长度信息到数组内,返回的就是长度的字节数

按照长度读取字节数。将需要的字节读取到目标数组,如果数组不够就要重新处理

如果发现你的代码有时候工作不正常,很可能你的mqtt源代码是被人更改过得。

第一个buf是用户提供给 该函数的一个空间,数据将按照mqtt格式化,buflen用户告诉该函数 这个buff只有这么大。DUP重复分发标志,首次发送为0,重复发送为1,qos为0必须为0.

packedid 本次通讯包标识,对于qos为1和2的情况为了解决tcp传输产生的重复问题,使用该id区分不同的包,一次通讯 比如 订阅 发送等,通讯过程只用一个相通的标识,占用的时候别人不可以使用该标识

通讯结束,释放。该标示最大0xffff。

topicfilter 主题过滤通配符组,也就是可以多个主题一次性发送,相应的节省一定的流量,但是订阅一般不是频繁的使用,所以可以酌情使用。另一个就是qos组。

原文地址:https://www.cnblogs.com/polar-lights/p/8963589.html