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組。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM