查看原文
其他

物联网MQTT—Connect控制报文

小师弟 果果小师弟 2022-05-20

点击上方“果果小师弟”,选择“置顶/星标公众号”

干货福利,第一时间送达!

前言:有很多小伙伴催更,所以MQTT终于来了,在学习MQTT之前啊,我们要明白MQTT通讯是通过很多的报文组成的,就好比二战时期发电报进行两军之间的通信。这个报文呢主要由三部分组成:固定报文+可变报文+有效载荷,这是官方起的名字,你可以把它理解为开头+正文+结尾,这样就好理解多了是吧!基本在MQQTT中所有的报文都由这三部分组成。比如这一章要说的Connect控制报文,顾名思义就是客户端(ESP8266)请求与服务端(阿里云服务器)建立连接的报文。啥意思呢?就好比你第一次去你女朋友家,你要首先打一个电话(Connect控制报文)征得叔叔阿姨的同意啊!叔叔阿姨同意之后(服务器确认建立连接)你才能去对吧,如果不同意或者电话没打通你就不能去你女朋友家啊,就算去了也不招待见对吧!

客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是connect报文。(因为客户端和服务端必须要建立连接后才能进行通信)。
1.CONNECT控制报文主要由三部分组成:固定报头、可变报头、有效载荷。
2.假设我们得到了固定报头是“liuyao”、可变报头是“iloveyou”、有效载荷是“zhuxiaoya”。我们要把这些字母转换成对应的16进制。然后再把它们串联起起来就得到。

1.固定报头

固定报头包含两个字节,第一个字节是固定的:0x10,第二个字节是是剩余长度字段,剩余长度等于可变报头的长度(10字节)加上有效载荷的长度。

1.1最终固定报头

综上我们可得固定报头为:10 ??(??我们在后面的实验会提到,先不着急)

2.可变报头


可变报头有四部分组成,协议名、协议级别、连接标志、保持连接。大家不要纠结为啥由这四部分组成,这是人家写这个协议的人规定的,你只要搞清楚这四部分对应的编码是啥就可以了,其余的四个字:不要纠结


2.1协议名

2.2协议级别

2.3连接标志

2.4保持连接

2.5总结

2.6最终可变报头

综上我们可得有效报头为: 00 04 4D 51 54 54  04 C2 00 64

3.有效载荷

有效载荷由三部分组成:客服端标识符、用户名、密码组成。

3.1原始数据

我们在阿里云物联网平台上创建一个设备后,会得下面这三个数据,这三个数据非常重要。

    "ProductKey": "a10zwkUxQUS",
    "DeviceName": "LY-1",
    "DeviceSecret": "d8b9915513b05d4de32fbed04566edd8" 
}
阿里云服务器地址(华东2) : *.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883
客户端ID : *|securemode=3,signmethod=hmacsha1|       
用户名 :    *&#                                  
密码 :      clientId*deviceName*productKey#

3.2加工后的数据

服务器地址:a10zwkUxQUS.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883
客户端ID :LY-1|securemode=3,signmethod=hmacsha1| 
用户名 :LY-1&a10zwkUxQUS
密码:clientIdLY-1deviceNameLY-1productKeya10zwkUxQUS
经过哈希加密:7a03368e740ff9efb8318c6ba2a0260f2a596f87
哈希加密在线计算网站:http://encode.chahuo.com/
之后要将客服端ID、用户名、经过哈希加密后的密码转换成16进制
客户端ID    :LY-1|securemode=3,signmethod=hmacsha1| 
用户名      :LY-1&a10zwkUxQUS
经过哈希加密 :7a03368e740ff9efb8318c6ba2a0260f2a596f87

3.3转换成16进制

客户端ID:LY-1|securemode=3,signmethod=hmacsha1| 转换为(16进制):
4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73
69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C      一共38个字节就是0x26
最终结果:把00 26加到最前面
00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C
73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C

用户名:LY-1&a10zwkUxQUS转换为(16进制):
4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53               一共16个字节就是0x10
最终结果:把00 10加到最前面
00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53 

经过哈希加密:7a03368e740ff9efb8318c6ba2a0260f2a596f87 转换为(16进制)
37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31
38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37     一共40个字节就是0x28
最终结果:把00 28加到最前面
00 28 37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 
31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37
最终可得:
  • 客户端:
    00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C
    73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C
  • 用户名:
    00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53
  • 密码:
    00 28 37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33
    31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37
  • 组合到一起:
    00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53  00 28 37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37

3.4最终有效载荷

这样我们就得到了有效载荷:
00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53  00 2837 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37

4.Connect控制报文

固定报头+可变报头+有效载荷
  • 10 ?? 00 04 4D 51 54 54 04 C2 00 64 00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53 00 28 37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37
现在要解决的就是"??",也就是我们最开始说的剩余长度。
这个问号??就是表示在问号后面有几个字符,有几个字符??就代表多少,然后把这个数字转换成16进制填入??就可以了。我们通过数数可以知道??后面有110个数,10进制的110转换成16进制就是0x6E。所以最终得到的CONNECT 控制报文为:
  • 10 6E 00 04 4D 51 54 54 04 C2 00 64 00 264C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53 00 28 37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37
通过网络调试助手发送connect报文
1.协议类型选择 TCP Client
2.本机地址:本机地址会在软件选择TCP Client后默认出现,不用手动选择
3.远程主机地址:这个就是我们创建设备后阿里云的远程地址
服务器地址:a10zwkUxQUS.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883 
4.在发送数据之前要先勾选按16进制发送,之后会在网络调试助手的接受端出现:20 02 00 00 说明发送正常接收正常,如果点击发送按钮之后网络调试助手马上就断开或者接收不到数据的话,就说明你发送的数据有问题,请仔细回去好好把报文数据整理一遍,否则不能发送成功。你要知道错的不可能是阿里云也不是MQTT协议,错的只有你的数据。
这里为啥是收到的是20 02 00 00 ,我们可以去看看数据手册中3.2小节的connect确认连接请求。

这样我们的客户端就与阿里云的服务端连接起来了,我们现在可以去看看阿里云官网就会发现此时的LY-1设备处于在线状态。哈哈,是不是很奇妙啊!

5.断开链接

我们可以看到数据手册的3.14小节,断开连接的报文是 E0 00

然后我们在连接状态下向服务器发从断开可连接的报文 E0 00,这是服务器就会与客户端断开,由于断开后收不到服务器发来的数据。所以网络调试助手不会接收到任何新消息。

这是我们再到阿里云官网(刷新一下网页)就会发现此时的LY-1设备处于离线状态。哈哈,是不是很奇妙啊!

我们用网络调试助手的目的就我们现在还没有单片机和esp8266,但是我们又必须要学习mqtt协议,只有通过网络调试助手来代替单片机来实现,等我们网络调试助手都调通了之后我们再把他一直到我们的STM32单片机中就可以了。

UDP-----为应用程序提供了一种无需建立连接就可以发送封装的IP数据包的方法
TCP Client  客户端------单片机(网络调试助手代替单片机)
TCP Server  服务端------阿里云
后台回复:MQTT,获取MQTT中文手册。


END

如果觉得文章对你有帮助,欢迎转发、留言、点赞、分享给你的朋友,感谢您的支持!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存