最近学习了W5500模块,并使用该模块实现MQTT通信,想对MQTT的学习,做个自己的总结(虽然网上已经有很多MQTT的详细介绍),方便以后查看。
https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/01-Introduction.html 一个较详细的MQTT协议介绍,本文一些截图来自该网站
一个MQTT数据包由以下三个部分组成:
1 Fixed Header 固定包头(ALL)
2 Variable Header 可变包头(部分类型包含)
3 Payload 负载信息(部分类型包含)
Part 1: Fixed Header
length : 2 Bytes - 5 Bytes
Byte 1 :
bit7-bit4 = MQTT包类型
bit3 - bit0 = MQTT包的标志
bit3 = DUP PUBLISH报文的重复分发标志 DUP=0:该条报文是第一次发送 DUP=1:该条报文之前已发送
bit2:1 = QoS PUBLISH报文的服务质量等级 00=最多发布一次 01=至少一次 10=只有一次
bit0 = RETAIN PUBLISH报文的保留标志(主要作用:在该条Publish报文发布后,该报文会存储在服务器端,当有新的订阅者订阅了该报文所属的主题,则新订阅者会马上收到该条报文)
Byte 2开始,最多4个字节
Remaining Length 剩余长度
如0x10 = 16字节长
0x1A 0x07 = 7*128+10字节长
C语言实现剩余长度编码和解码
//将长度len编码后 存到buf
void encode_remaining_len(unsigned char* buf, int len)
{
unsigned char index = 0;
unsigned char tmp = 0;
do{
tmp = len%0X80;
len /= 0X80;
if(len > 0){
tmp |= 0X80;
}
buf[index++] = tmp;
}while(len>0);
}
//将buf内解码,返回长度
int decode_remaining_len(unsigned char* buf)
{
int len = 0;
unsigned char index = 0;
unsigned char tmp = 1;
do{
len += (buf[index]&0X7F)*tmp;
tmp *= 0X80;
}while(buf[index++]&0X80);
return len;
}
Part 2: Variable Header
length = 2 Bytes
该部分只有在包类型为PUBLISH(QoS > 0), PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE, SUBACK,UNSUBSCIBE,UNSUBACK才有
目前我在学习时在订阅(Subscribe)时有使用,个人理解该部分的作用是标记数据包的,作为数据包的ID(请大家指点)
Part3:Payload
根据不同包类型,该部分的内容不同
以Connect 包为例总结下:
0X10 0X0f 0X00 0X04 0X4d 0X51 0X54 0X54 0X04 0X02 0X0b 0Xb8 0X00 0X03 0X31 0X2d 0X73
Part1:
Byte1:表示包类型为连接
Byte2:剩余长度=15
Part2:无
Part3:
Byte3-Byte4:表示协议名字的长度=4
Byte5-Byte8=字符"MQTT"
Byte9:MQTT3.1.1固定为4
Byte10:之后详解
Byte11-Byte12(0X0b 0Xb8): 保持服务器连接时间=3000s
Byte13-Byte14:ClientID长度
Byte15-Byte17:ClientID = 1-s