news 2026/7/15 4:50:20

STM32学习笔记【37.MQTT协议】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32学习笔记【37.MQTT协议】

文章目录

  • 前言
  • 一、MQTT是什么?
  • 二、MQTT原理
    • 1.服务端
    • 2. 客户端
    • 3. 主题
    • 4. 发布与订阅的特点
  • 三、MQTT报文
    • 1. 报文结构
    • 2. 固定报头
      • 2.1 消息类型(Message type)
      • 2.2 标志位【DUP、QoS Level、RET】
      • 2.3 剩余长度(Remaining Length)
    • 3. 可变报头
    • 4. 有效载荷
  • 四、QoS,服务质量
  • 五、MQTT心跳机制
  • 六、MQTT遗嘱
  • 七、报文案例
    • 1. OneNet配置
    • 2. 常用报文
    • 3. 对常用报文的实际操作
      • 3.1 CONNECT报文
        • 1. 固定报头:10 XX
        • 2. 可变报头:00 04 4D 51 54 54 04 C2 00 64
        • 3. 有效载荷
      • 3.2 CONNACK报文
        • 1. 固定报头【20 02】
        • 2. 可变报头
      • 3.3 SUBSCRIBE报文
        • 1. 固定报头【82 XX】
        • 2. 可变报头【报文名字:00 0A】
        • 3. 有效载荷
      • 3.4 SUBACK报文
        • 1. 固定报头
        • 2. 可变报头
        • 3. 有效载荷
      • 3.5 UNSUBSCRIBE报文
        • 1. 固定报头【A2 XX】
        • 2. 可变报头
        • 3. 有效载荷
      • 3.6 UNSUBACK报文
        • 1. 固定报头
        • 2. 可变报头
      • 3.7 PUBLISH报文
        • 1. 固定报头【30 XX】
        • 2. 可变报头
        • 3. 有效载荷
      • 3.8 PINGREQ报文和PINGRESP报文
        • 1. 固定报头
  • MQTT报文小结
  • 总结

前言

MQTT协议是当今世界上最受欢迎的物联网协议,没有之一。MQTT协议为设备提供了稳定、可靠、简单易用的通信基础,截止目前通过MQTT协议连接的设备已经过亿,广泛应用于IoT、M2M等领域。
目前MQTT主流版本有MQTT3.1.1和MQTT5。MQTT5完全兼容MQTT3.1.1,是在MQTT3.1.1的基础上进行完善补充。

一、MQTT是什么?

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)协议是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的、客户端服务端【BS】架构的、发布/订阅模式的消息传输协议。

MQTT协议特点:

  • 简单易用,方便集成。
  • 安全可靠,支持TLS/SSL加密和认证机制
  • 轻量级,占用带宽小,支持多种消息传输模式
  • 灵活性,可知设备连接状态,可控数据传输质量

二、MQTT原理

在MQTT协议通讯中,最重要的两个角色是服务端和客户端。客户端向一【主题】【发布】消息,服务端处理并推送给【订阅】了该【主题】的其他客户端。

简单举例说:将整个MQTT比作我们熟悉的视频软件,对应关系如下——

抖音MQTT
抖音服务器服务端
所有抖音用户客户端
抖音用户关注某个抖音博主【动作】订阅
博主发布视频发布

1.服务端

MQTT服务端通常是一台服务器,它充当着MQTT信息传输的中心节点。其主要功能是接收来自确保客户端之间的通信畅通无阻,并确保MQTT消息被正确接收和准确投递。


服务端一般就是云平台,OneNET、阿里云、腾讯云登;也可以用EMQ或Mosquitto自己搭建服务端。

2. 客户端

MQTT客户端可以向服务端通过【发布】发送信息,也可以从服务端【订阅】来收取信息。
客户端一般是我们的单片机,STM32、C51、树莓派等。

3. 主题

在MQTT通讯中,客户端订阅的是一个个【主题】。MQTT服务端在管理信息通讯时,使用【主题】来控制。

4. 发布与订阅的特点

  • 相互独立:客户端相互独立,彼此没有直接联系,不用知道对方的任何状态、情况。
  • 空间分离:客户端只要连接同一个MQTT通讯网络,无论是互联网或者局域网都可以通讯。
  • 时间异步:客户端的发布与订阅无需同步。若有客户端断连,服务端保存信息,待客户端上线后推送。

三、MQTT报文

MQTT协议通过交换预定义的MQTT控制报文来通信。MQTT控制报文简称MQTT报文。

1. 报文结构

  • 固定报头(Fixed header):所有MQTT报文有,表示报文类型及报文的
  • 可变报头(Variable header):部分MQTT报文有,报文类型决定了可变头是否存在及其具体内容。
  • 有效载荷/消息体(Payload):部分MQTT报文有,存放报文的具体内容。

2. 固定报头

图中是竖着,实际每个byte【字节】是横着排列

2.1 消息类型(Message type)

位于byte1的第7~4位,表示MQTT报文类型,有下面那么多类型:

名称报文流动方向描述
Reserved0禁止保留位
CONNECT1客户端到服务器客户端请求连接到服务器
CONNACK2服务器到客户端连接确认
PUBLISH3双向发布消息
PUBACK4双向发布确认
PUBREC5双向发布收到(保证第1部分到达)
PUBREL6双向发布释放(保证第2部分到达)
PUBCOMP7双向发布完成(保证第3部分到达)
SUBSCRIBE8客户端到服务器客户端请求订阅
SUBACK9服务器到客户端订阅确认
UNSUBSCRIBE10客户端到服务器请求取消订阅
UNSUBACK11服务器到客户端取消订阅确认
PINGREQ12客户端到服务器心跳请求
PINGRESP13服务器到客户端心跳响应
DISCONNECT14客户端到服务器中断连接
Reserved15禁止保留位

2.2 标志位【DUP、QoS Level、RET】

位于byte1的第3~0位,表示MQTT报文的分类组表示。

  • DUP:发布消息的副本【一般为0】
  • QoS:发布消息的服务质量
  • RETAIN:发布保留标识【一般为0】

2.3 剩余长度(Remaining Length)

位于byte1的第3~0位,表示当前剩余字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。

3. 可变报头

它在固定头和有效载荷之间。可变头的内容根据报文类型的不同而不同。可变头的报文标识符字段存在于多个类型的报文里。

4. 有效载荷

有效载荷是应用消息,但并不是所有的报文都有有效载荷,只有部分MQTT报文有有效载荷,具体如下:

控制报文有效载荷
CONNECT需要
CONNACK不需要
PUBLISH可选
PUBACK不需要
PUBREC不需要
PUBREL不需要
PUBCOMP不需要
SUBSCRIBE需要
SUBACK需要
UNSUBSCRIBE需要
UNSUBACK不需要
PINGREQ不需要
PINGRESP不需要
DISCONNECT不需要

四、QoS,服务质量

MQTT协议有三种服务质量级别:

  • QoS = 0:最多发一次【不管你是否接收,我都会发一次】
  • QoS = 1:最少发一次【如果你没收到,我就会一直发】
  • QoS = 2:保证收一次【保证服务端一定要收到这条信息】

五、MQTT心跳机制

⚠️确保服务端与客户端正常通信,固定时间客户端给服务端发数据包,服务端给客户端返回一个数据包,说明该通信正常。后面可以正常发消息。

六、MQTT遗嘱

MQTT遗嘱是一种机制,允许客户端在【活着】的时候设置并发送遗嘱消息,以便在客户端意外断线时由服务端公布。

意外断线:当客户端在没有发送DISCONNECT报文的情况下失去了心跳信号,通常发生在网络故障或电池耗尽等情况下。此时,服务端会察觉到客户端的异常断开,并将客户端的遗嘱通过合理设置和使用MQTT遗嘱机制,可以增强客户端在服务端管理中的作用,并提供实时的设备状态信息。

七、报文案例

创建产品和设备:

  • 产品:一组具有相同功能定义的设备集合,产品下的资源包括设备、设备数据、设备权限、数据触发服务以及基于设备数据的应用等多种资源,用户可以创建多个产品。

  • 设备:归属于某一个产品下,是真实设备在平台的映射,用于和真实设备通过连接报文建立连接关系,平台资源分配的最小单位,设备之间的通过设备名称来区分。

通俗讲,产品好比一款华为手机,设备就是华为nova2、华为nova3…。

1. OneNet配置

  1. 浏览器搜索OneNet → 进入官网 → 用户注册 → 点击开发者中心 → 创建产品和设备



  1. 创建产品步骤:产品开发 → 设置物模型 → 添加自定义功能点 → 点击新增 → 点击保存+确定 → 保存成功

  1. 创建设备步骤:设备管理 → 创建设备 → 填写所属产品和设备名称 → 确定

    创建完设备后,点击设备详情,下图这三个地方非常重要,一定要复制粘贴保存好。也叫MQTT三元组,在其他地方可能是其它叫法,但意思一样。
    通过MQTT三元组连接到MQTT

2. 常用报文

客户端给服务端发送CONNECT,表示我要开始连接你,服务端给客户端回复一个CONNECTACK信息,表示连接成功/失败。
客户端给服务端订阅一条消息,服务端收到SUBSCRIBE报文,了解客户端想要什么,就会给客户端回复SUBACK报文。
如果是取消订阅,客户端会给服务端发送UNSUBSCRIBE报文,服务端收到后,知道客户端不想要什么,就会给客户端发送UNSUBACK报文。
如果主动往服务端发送消息,则给服务端发送一个PUBLISH报文。这时QoS = 0,只管发,不管你是否收到什么消息。
如果定时告诉服务器,客户端目前的状况,就发送PINGREQ,服务器也会给客户端回复PINGRESP

3. 对常用报文的实际操作

3.1 CONNECT报文

1. 固定报头:10 XX

2. 可变报头:00 04 4D 51 54 54 04 C2 00 64

协议名和协议级别:【00 04 4D 51 54 54】

连接标志:【C2】


标1的位是用到的。

保持连接:客户端与服务器保持连接,如果没有数据连接,最长可以保持多久?如果一直连接,会消耗服务端资源。

以CONNECT报文的可变头为例,将协议名、协议级别、连接标志、保持连接按十六进制顺序组合起来,为:00 04 4D 51 54 04 C2 00 64。

3. 有效载荷

有效载荷 = 设备ID + 产品ID +token

如何获取token?


token各个参数填写:

名称类型参数说明参数示例
resstring访问资源resource格式:products/{产品ID}/devices/{设备名字}products/6G4MCSB12E/devices/vibrate01
etint访问过期时间,单位秒,unix时间。当一次访问参数中的et时间小于当前时间时,平台会认为参数过期从而拒绝该访问1815491530表示: 北京时间 2027-07-13 15:12:10
keystringMQTT三元组的设备秘钥SHVuVm9ZcDAxUVNQSWNOcG5VREtrYVlsZDVDZTJCd2U=
methodstring加密方式,支持hmacmd5、hmacsha1、hmacsha256md5(代表使用hmacmd5算法)、sha1(代表使用hmacsha1算法)、sha256(代表使用hmacsha256 算法)
versionstring参数组版本号,日期格式,目前仅支持“2018-10-31”2018-10-31

最终CONNECT报文:

这是之前出问题的报文:

10 6800 04 4D 51 54 54 04 C2 00 64
设备ID:00 0976 69 62 72 61 74 65 30 31
产品ID:00 0A36 47 34 4D 43 53 42 31 32 45
Token:00 4576 65 72 73 69 6F 6E 3D 32 30 31 38 2D 31 30 2D 33 31 26 72 65 73 3D 70 72 6F 64 75 63 74 73 25 32 46 36 47 34 4D 43 53 42 31 32 45 25 32 46 64 65 76 69 63 65 73 25 32 46 76 69 62 72 61 74 65 30 31 26 65 74

这是正确的报文:

固定报头:10
剩余长度【165字节】:A5 01
协议名:00 04
MQTT:4D 51 54 54
协议级别:04
连接标志:C2
Keep Alive:00 64 (100秒)
设备ID:00 09 76 69 62 72 61 74 65 30 31
产品ID:00 0A 36 47 34 4D 43 53 42 31 32 45
密码【onenet-toke生成工具】:00 82 76 65 72 73 69 6F 6E 3D 32 30 31 38 2D 31 30 2D 33 31 26 72 65 73 3D 70 72 6F 64 75 63 74 73 25 32 46 36 47 34 4D 43 53 42 31 32 45 25 32 46 64 65 76 69 63 65 73 25 32 46 76 69 62 72 61 74 65 30 31 26 65 74 3D 31 38 31 35 34 39 31 35 33 30 26 6D 65 74 68 6F 64 3D 73 68 61 31 26 73 69 67 6E 3D 6A 51 62 6A 69 38 55 61 72 49 55 37 25 32 46 6C 51 51 37 57 55 38 7A 70 62 66 49 37 77 25 33 44

完整CONNECT报文:

10 A5 01 00 04 4D 51 54 54 04 C2 00 64 00 09 76 69 62 72 61 74 65 30 31 00 0A 36 47 34 4D 43 53 42 31 32 45 00 82 76 65 72 73 69 6F 6E 3D 32 30 31 38 2D 31 30 2D 33 31 26 72 65 73 3D 70 72 6F 64 75 63 74 73 25 32 46 36 47 34 4D 43 53 42 31 32 45 25 32 46 64 65 76 69 63 65 73 25 32 46 76 69 62 72 61 74 65 30 31 26 65 74 3D 31 38 31 35 34 39 31 35 33 30 26 6D 65 74 68 6F 64 3D 73 68 61 31 26 73 69 67 6E 3D 6A 51 62 6A 69 38 55 61 72 49 55 37 25 32 46 6C 51 51 37 57 55 38 7A 70 62 66 49 37 77 25 33 44

固定报头中的剩余长度值:
除了固定报头,剩余的可变报头+有效载荷


一个字节有8位二进制,最多是11111111应该能256才对,为什么单字节最多表示127呢?
因为剩余长度是使用变长度编码方案,低7位(第0~6位)用于编码数据,最高有效位(第7位)用于表示是否有更多字节,最大可以使用4个字节。
第7位是标志位。

MQTT设备连接:

  1. 复制地址到网络调试助手,端口号是1883,点击链接;
  2. 复制CONNECT报文,并发送


收到“20 02 00 00”和“20 02 00 04”,思维字节是服务端返回的CONNACK报文
“00”表示连接已被服务端接受,连接成功;
“04”表示用户名或密码的数据格式无效,可能是有效载荷没写对。

  1. 设备处于在线状态

3.2 CONNACK报文


CONNACK报文由固定报头和可变报头组成,没有有效载荷。

1. 固定报头【20 02】

2. 可变报头


连接确认标志的位7~1是保留位且必须设置为0。第0(SP)位是当前会话(Session Present)标志,如果没有保存的会话状态或收到清理会话命令则为0,如果收到保存会话则为1.

连接返回码表示连接结果,有以下几种情况:

返回码响应描述
0x00连接已接受连接已被服务端接受
0x01连接已拒绝,不支持的协议版本服务端不支持客户端请求的MQTT协议级别
0x02连接已拒绝,不合格的客户端标识符客户端标识符是正确的UTF-8编码,但服务端不允许使用
0x03连接已拒绝,服务端不可以网络连接已建立,但MQTT服务不可用
0x04连接已拒绝,无效的用户名或密码用户名或密码的数据格式无效
0x05连接已拒绝,未授权客户端未被授权连接到此服务器
6-255保留

20 02 XX XX

3.3 SUBSCRIBE报文

SUBSCRIBE报文用于客户端请求订阅主题。订阅某主题之后,所有发布的该主题的消息我们都可以收到。
一条SUBSCRIBE报文由固定报头、可变报头、有效载荷组成。

1. 固定报头【82 XX】

2. 可变报头【报文名字:00 0A】

3. 有效载荷

有效载荷由主题过滤器服务质量要求组成


长度 = 44, 十六进制是2A
有效载荷=长度+主题过滤器+服务质量要求 = 00 2C 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 00

主题过滤器:$sys/6G4MCSB12E/vibrate01/thing/property/set

SUBSCRIBE报文:
固定报头:82 【32】XX
可变头:00 0A
有效载荷【主题过滤器长度44字节】:00 2C
有效载荷【主题过滤器】:24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 73 65 74
有效载荷【QoS】:00

XX后面的字节长度:49个 = 十六进制31

SUBSCRIBE报文:
82 31 00 0A 00 2C 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 00

出现的问题:拒绝订阅

出现问题的原因:
设备ID:vibrate01,不是vibrate1;注意计算二进制数时,注意不要加空格,否则也算入字节数,导致订阅失败。【⚠️仔细!!!】

3.4 SUBACK报文

一条SUBACK报文由固定报头、可变报头、有效载荷组成。

1. 固定报头

2. 可变报头

3. 有效载荷


在MQTT协议里,SUBACK中的返回码是:

返回码描述
00订阅成功,QoS 0
01订阅成功,QoS 1
02订阅成功,QoS 2
80订阅失败(Failure)

发送的服务质量等级是多少就返回多少。

3.5 UNSUBSCRIBE报文

UNSUBSCRIBE报文,客户端向服务端发送,用于取消订阅主题,取消某订阅主题后,就不会收到该主题的新消息了。

UNSUBSCRIBE报文由固定报头、可变报头、有效载荷组成。

1. 固定报头【A2 XX】

2. 可变报头

随意取名字:00 0B

3. 有效载荷

该报文与SUNSCRIBE报文同理,只是该报文无服务质量。
最终UNSUBSCRIBE报文:
固定报头:A2 XX
可变报头:00 0B
有效载荷长度:00 2C
有效载荷主题过滤器:24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 73 65 74

XX后面的是48个,十六进制是30

UNSUBSCRIBE报文:
A2 30 00 0B 00 2C 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 73 65 74

成功取消订阅:

3.6 UNSUBACK报文

UNSUBACK报文,取消订阅确认,适用于服务端回复客户端表示自己收到了UNSUBSCRIBE报文。

一条UNSUBACK报文由固定报头、可变报头组成。

1. 固定报头

2. 可变报头


发送UNSUBSCRIBE报文后,收到B0 02 00 0B,即成功取消订阅。

3.7 PUBLISH报文

PUBLISH报文,发布消息,是双向的,既可以客户端到服务端,也可以服务端到客户端。但是需要注意发布消息只能在同一产品ID下进行,不能进行跨产品消息推送。

1. 固定报头【30 XX】

2. 可变报头

可变报头由主题名报文标识符组成。

$sys/6G4MCSB12E/vibrate01/thing/property/post转成十六进制是:
24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74
共45个字符,加上长度前缀 00 2D,可变报头为:00 2D 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74

3. 有效载荷

发布的内容是有效载荷,其格式必须是JSON格式,也要转为十六进制。

注意:这里不需要以长度为前缀了,因为是JSON格式,不是UTF-8。

JSON格式规则如下:

  • 对象用方括号[ ]表示。
  • 对象用大括号{ }表示。
  • 名称/值对组合成数组和对象。
  • 名称置于双引号中,值有字符串、数值、布尔值、null、对象和数组。
  • 并列的数据之间用逗号 ,分隔
{"id":"7635219","version":"1.0","params":{"receive":{"value":"66666"}}}

PUBLISH报文:
固定报头:30 XX
可变报头【47字节】:00 2D 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74
有效载荷【71个字节】:7B 22 69 64 22 3A 22 37 36 33 35 32 31 39 22 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 72 65 63 65 69 76 65 22 3A 7B 22 76 61 6C 75 65 22 3A 22 36 36 36 36 36 22 7D 7D 7D
剩余长度XX:76
00 2D 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74 00 47 7B 22 69 64 22 3A 22 37 36 33 35 32 31 39 22 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 72 65 63 65 69 76 65 22 3A 7B 22 76 61 6C 75 65 22 3A 22 36 36 36 36 36 22 7D 7D 7D

完整PUBLISH报文:
30 76 00 2D 24 73 79 73 2F 36 47 34 4D 43 53 42 31 32 45 2F 76 69 62 72 61 74 65 30 31 2F 74 68 69 6E 67 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74 7B 22 69 64 22 3A 22 37 36 33 35 32 31 39 22 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 72 65 63 65 69 76 65 22 3A 7B 22 76 61 6C 75 65 22 3A 22 36 36 36 36 36 22 7D 7D 7D

出现的问题:
为什么PUBLISH报文没问题,数据还是没收到?
因为JSON代码中通过**标识符“receive”**来接收数据,在创建自定义功能时,一定要写好标识符。

3.8 PINGREQ报文和PINGRESP报文

PINGREQ报文和PINGRESP报文是心跳请求和心跳响应,是MQTT心跳机制的两个报文。客户端定时向服务端发送心跳请求(PINGREQ),告诉服务端,我还和你连着哦。服务端收到心跳请求后,会回复一条心跳响应(PINGRESP),告诉客户端,我知道你还连着我啦。

通过心跳机制,MQTT可以实时监测客户端的连接状态,及时发现和处理异常情况,确保通信的可靠性和稳定性。

1. 固定报头

PINGREQ报文和PINGRESP报文,只有固定报头。

PINGREQ报文,二进制:1100 0000 0000 0000,十六进制:C0 00。


发送心跳请求 C0 00
返回心跳响应 D0 00

MQTT报文小结

L表示长度前缀,两位字符;
剩余长度是1位字符

名称报文流动方向描述公式
CONNECT客户端到服务器客户端请求连接到服务器10 + 剩余长度 + 00 04 4D 51 54 54 04 C2 + 保持连接时间 + L + 设备ID + L + 产品ID + L + token
CONNACK服务器到客户端连接确认20 02 + 返回码
SUBSCRIBE客户端到服务器客户端请求订阅82 + 剩余长度 + 标识符 + L + 主题过滤器 + QoS
SUBACK服务器到客户端订阅确认90 03 + 标识符 + 返回码
PUBLISH双向发布消息30 + 剩余长度 + L + 主题 + 数据(JSON)
UNSUBSCRIBE客户端到服务器请求取消订阅A2 + 剩余长度 + 标识符 + 主题
UNSUBACK服务器到客户端取消订阅确认B0 02 + 标识符
PINGREQ客户端到服务器心跳请求C0 00
PINGRESP服务器到客户端心跳响应D0 00

总结

通过本文的学习,相信对MQTT一定有了深度的了解和认识,接下来开始做MQTT编程实战吧。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 4:49:18

Cocos Creator安卓打包全攻略:从环境配置到Release签名避坑指南

1. 项目概述:为什么安卓打包总让人头疼?如果你用 Cocos Creator 3.x 开发过游戏,并且尝试过打包成安卓 APK,那你大概率经历过这样的场景:在编辑器里跑得好好的游戏,一到打包环节,各种报错就像雨…

作者头像 李华
网站建设 2026/7/15 4:47:07

Soft Prompt参数高效微调:Prompt-Tuning深度解析

引言 近年来,以 GPT-4、PaLM-2 等为代表的超大规模语言模型在众多 NLP 任务上刷新了性能上限。然而,将这些千亿甚至万亿参数模型完整复制并梯度更新(Full Fine-Tuning)所产生的计算与存储成本,令绝大多数团队望而却步…

作者头像 李华
网站建设 2026/7/15 4:46:32

ESP32/ESP8266与AMG8833:构建无线热成像Android监控系统

1. 项目概述:低成本热成像监控方案想象一下,用不到200元的硬件成本就能搭建一套可远程查看的热成像系统——这就是ESP32/ESP8266搭配AMG8833传感器带来的可能性。这个方案特别适合需要非接触式温度监测的场景,比如智能家居中的电器发热监控、…

作者头像 李华
网站建设 2026/7/15 4:45:13

Java程序设计(第3版)第四章——接口的分类

接口的分类 1.常量接口:接口中只有静态常量,没有定义任何方法,应用不广泛 2.标记接口:空接口,接口中没有定义任何的属性和方法 3.普通接口:具有至少一个抽象方法的接口 4.函数式接口:接口中只有一个抽象方法&#xff0…

作者头像 李华
网站建设 2026/7/15 4:44:19

AI代理协作系统:模拟游戏工作室的LLM结构化应用实践

1. 项目概述:当AI学会“开公司”如果你是一名独立游戏开发者,或者是一个小型创意团队的核心成员,那么下面这个场景你一定不陌生:深夜,你对着空白的代码编辑器或设计文档,脑子里有无数个关于新游戏的绝妙想法…

作者头像 李华
网站建设 2026/7/15 4:43:21

Python agentflare-sdk 包详解:安装、语法、参数与实战案例

1. 引言agentflare-sdk 是一个面向 AI Agent 开发的 Python SDK,旨在简化智能体(Agent)的构建、部署与编排流程。它提供了统一的接口来管理 LLM 调用、工具注册、记忆存储和多 Agent 协作,适合从原型验证到生产部署的全链路开发。…

作者头像 李华