✅ 操作成功!

mqtt协议详解

发布时间:2023-06-16 作者:admin 来源:文学

mqtt协议详解

mqtt协议详解

过亚弥乃-幼儿园食堂

2023年3月20日发(作者:南园小学)

mqtt协议分析

mqtt协议分析

⼀.mqtt报⽂

mqtt报⽂包括,固定报头,可变报头,有效载荷(消息体)。

1.固定报头

mqttcontrolpackettype:

flagsspecifictoeachmqttcontrolpackettype:

dup:客户端与服务器消息重发时,此标志被置1

qos:消息质量等级,最多⼀次(QoS0),⾄少⼀次(QoS1),有且仅有⼀次(QoS2)

retain:是否保持此条消息,1为保持

2.可变报头

不同类型消息其参数不⼀样,现在以connect类型为例。

这⾥解释下连接标志与保活计时器

usernameflag:值为1,连接mqtt需要⽤户名,存在于有效载荷⾥

passwordflag:值为1,连接mqtt需要密码,存在于有效载荷⾥

所以,如果连接mqttservice需要⽤户名和密码,这两位需要置1。

willretain,willqos,willflag:控制客户端与服务器异常断开,发送will消息给客户端,如果willflag被置1,willretain与willqos设置将

会被⽣效,并且在有效载荷填写相关字段内容。

保活计时器:客户端设定⼀段时间给服务器发送⼀个ping包,⽤于探测⼆者是否还处于正常连接状态。

3.有效载荷

存放着客户端与服务器之间需要传输的数据,不同消息类型,其携带的数据也不⼀样。

CONNECT:

该有效载荷包含了⼀个或多个UTF-8编码字符串。它们包括标识客户端的唯⼀标识符、Will

主题和消息、要使⽤的⽤户名和密码。其中只有第⼀项是必选的,其余的取决于可变消息头

部中的标志置位情况

SUBSCRIBE:

该有效载荷包含⼀系列要订阅的主题名,以及每个主题的QoS级别。这些字符串都是UTF

编码的。

PUBLISH:

该有效载荷只包含应⽤特定的数据。

⼆.wireshark抓包分析mqtt协议

设备开机,连接mqtt服务器,订阅发布消息,并且定时ping服务器的完整log如下图。

connect报⽂:

报⽂内容解析(补充,与上图不是⼀个mqtt包):

subscribe报⽂:

报⽂内容解析(补充,与上图不是⼀个mqtt包):

publish报⽂:

msglen属于固定报头,mqtt报⽂剩余长度

三.mqtt源码实现

本⽂已CONNECT类型为例,其他都是类似的,封装报⽂,发送数据包;

//封装报⽂

if((len=MQTTSerialize_connect(c->buf,c->buf_size,options))<=0)

gotoexit;

//发送报⽂

if((rc=sendPacket(c,len,&connect_timer))!=SUCCESS)//sendtheconnectpacket

gotoexit;//therewasaproblem

intMQTTSerialize_connect(unsignedchar*buf,intbuflen,MQTTPacket_connectData*options)

{

unsignedchar*ptr=buf;

MQTTHeaderheader={0};

MQTTConnectFlagsflags={0};

intlen=0;

intrc=-1;

FUNC_ENTRY;

if(MQTTPacket_len(len=MQTTSerialize_connectLength(options))>buflen)

{

{

rc=MQTTPACKET_BUFFER_TOO_SHORT;

gotoexit;

}

=0;

=CONNECT;//mqtt包类型

writeChar(&ptr,);/*writeheader*/

ptr+=MQTTPacket_encode(ptr,len);/*writeremaininglength*/

if(options->MQTTVersion==4)//mqtt协议版本

{

writeCString(&ptr,"MQTT");

writeChar(&ptr,(char)4);

}

else

{

writeCString(&ptr,"MQIsdp");

writeChar(&ptr,(char)3);//mqtt协议名称

}

//mqttconnect连接标志

=0;

ession=options->cleansession;

=(options->willFlag)?1:0;

if()

{

S=options->;

tain=options->ed;

}

if(options->g||options->)

me=1;

if(options->g||options->)

rd=1;

writeChar(&ptr,);

writeInt(&ptr,options->keepAliveInterval);//保活计时器

//有效载荷

writeMQTTString(&ptr,options->clientID);

if(options->willFlag)

{

writeMQTTString(&ptr,options->ame);

writeMQTTString(&ptr,options->e);

}

if(me)

writeMQTTString(&ptr,options->username);

if(rd)

writeMQTTString(&ptr,options->password);

rc=ptr-buf;

exit:FUNC_EXIT_RC(rc);

returnrc;

}

本⽂部分内容参考mqtt-v3.1协议规范,可⾃⾏去查看详细内容。

👁️ 阅读量:0