有空了和你們分享一下,如何從頭架構一個高效mqtt並行客戶端,基於傳統GPRS等較差網絡環境和網關等網絡環境好的情景(固然仔細講解mqtt的基本函數使頗有必要的)。---這會正忙着搬磚html
MQTt協議 第一個字節用來表示報表類型git
接下來第二個字節開始是剩餘長度數組
表示長度,最多用4個字節,變長,每一個字節的高位表示後面是否還有表示長度的字節,也就是說每一個字節能夠表示128個字節的長度網絡
本篇標註 標識符適用於qos大於0的狀況。架構
其餘細節 socket
https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/02-ControlPacketFormat.htmltcp
本文要點函數
/** * 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個字節this
/** * 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組。