有空了和你们分享一下,如何从头架构一个高效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组。