MQTT协议:IoT通信的轻量级选手

文章总结(帮你们节约时间)

  • MQTT协议是一种轻量级的发布/订阅通信协议。
  • MQTT通信包括连接建立、订阅、发布和断开等过程。
  • MQTT基于TCP/IP,其通信过程涉及多种控制包和数据包。
  • ESP32S3可以通过MQTT协议接收消息来控制IO9引脚上的LED。

想象一下,如果互联网是一个繁忙的城市,那么MQTT就像是一个高效的快递系统。而传统HTTP通信?那就是你不得不亲自上门取包裹的情况!MQTT(Message Queuing Telemetry Transport)是物联网世界的通信明星,它轻巧、灵活,特别适合资源受限的设备。这不就像是那种即使在拥挤的小巷里也能灵活穿梭的电动车吗?

MQTT是什么?

MQTT是一种基于发布/订阅模式的轻量级消息传输协议,专为低带宽、高延迟或不稳定网络环境设计。它最初由IBM开发,现已成为物联网领域的标准协议之一。

想象MQTT就像是一个神奇的广播站。你不需要直接联系想要交流的对象,只需对着广播站(MQTT服务器,也称为Broker)说:“我要订阅’天气频道’”。之后,任何发布到"天气频道"的信息,你都能收到!这种解耦的设计使得设备之间不需要知道彼此的存在,大大简化了网络拓扑。

MQTT的核心概念

主题(Topic)

MQTT的主题就像是邮件的地址系统,但更加灵活。主题由层级组成,用斜杠分隔,例如:home/livingroom/temperature

这种层级结构有什么妙处?你可以使用通配符订阅多个主题!例如,订阅home/#就能收到家中所有传感器的数据,而不用一个个地订阅。这不比传统的点对点通信方便多了吗?

QoS(服务质量)

MQTT提供三种服务质量级别:

  • QoS 0:最多一次,“发了就发了,管它收没收到”
  • QoS 1:至少一次,“我会一直发,直到收到确认”
  • QoS 2:正好一次,“我保证消息只送达一次,不多不少”

这就像是你发送一封重要邮件,QoS决定了你会不会追踪它、催促它、确认它是否送达。

MQTT通信过程详解

连接建立过程

想知道MQTT客户端和服务器之间的第一次"握手"是怎样的吗?请看下面的详细步骤:

  1. TCP连接建立:MQTT建立在TCP/IP协议之上,首先需要完成TCP三次握手:

    • 客户端发送SYN包(序列号=x)
    • 服务器回复SYN-ACK包(序列号=y,确认号=x+1)
    • 客户端发送ACK包(确认号=y+1)
  2. CONNECT包发送:TCP连接建立后,客户端发送CONNECT包,包含:

    • 客户端ID
    • 用户名和密码(如果需要认证)
    • 保持连接的时间间隔(Keep Alive)
    • 清除会话标志(Clean Session)
    • 遗嘱信息(Will Message,在客户端异常断开时发送的消息)
  3. CONNACK响应:服务器回复CONNACK包,告知连接是否成功,包含:

    • 连接返回码(0表示成功,其他值表示各种错误)
    • 会话状态标志(指示是否有上一个会话)

想象这个过程就像是你走进一个俱乐部,先向保安出示会员卡(TCP连接),然后向接待员登记你的信息(CONNECT),最后接待员确认你可以进入并告诉你你的会员状态(CONNACK)。

发布/订阅过程

  1. 订阅过程

    • 客户端发送SUBSCRIBE包,指定要订阅的主题和QoS级别
    • 服务器回复SUBACK包,确认订阅并返回授予的QoS级别
  2. 发布过程

    • 发布者发送PUBLISH包,包含主题、消息内容和QoS级别
    • 如果QoS > 0,则需要额外的确认包(PUBACK、PUBREC、PUBREL、PUBCOMP)
  3. QoS 1的消息流

    • 发布者→PUBLISH→服务器
    • 服务器→PUBACK→发布者
    • 服务器→PUBLISH→订阅者
    • 订阅者→PUBACK→服务器
  4. QoS 2的消息流

    • 发布者→PUBLISH→服务器
    • 服务器→PUBREC→发布者
    • 发布者→PUBREL→服务器
    • 服务器→PUBCOMP→发布者
    • 服务器→PUBLISH→订阅者
    • 订阅者→PUBREC→服务器
    • 服务器→PUBREL→订阅者
    • 订阅者→PUBCOMP→服务器

看到这些确认过程,是不是觉得QoS 2有点繁琐?但这正是为了保证消息"正好一次"传递的代价!就像快递公司为了确保贵重包裹安全送达,会要求你签名、拍照、确认收货一样。

保持连接与断开

  • PINGREQ/PINGRESP:客户端定期发送心跳包,服务器回应以保持连接活跃
  • DISCONNECT:客户端发送断开连接的请求,然后关闭TCP连接

这就像是你在图书馆学习,偶尔举手让管理员知道你还在(PING),最后向管理员示意你要离开(DISCONNECT)。

MQTT底层TCP数据包分析

当MQTT协议工作时,TCP层都发生了什么呢?让我们揭开这个神秘的面纱:

  1. TCP连接建立(三次握手):

    客户端 -> [SYN] -> 服务器
    客户端 <- [SYN, ACK] <- 服务器
    客户端 -> [ACK] -> 服务器
    
  2. MQTT CONNECT包

    TCP头部:源端口: 随机端口(如43251)目标端口: 1883(标准MQTT端口)序列号: x确认号: y标志: PSH, ACKMQTT数据:包类型: CONNECT (1)剩余长度: 可变协议名: "MQTT"协议级别: 4(MQTT v3.1.1)或5(MQTT v5.0)连接标志: 用户名、密码、遗嘱等标志位保持连接: 通常为60秒客户端标识符: 如"esp32_client_001"[可选]用户名、密码等
    
  3. MQTT PUBLISH包(QoS 1)

    TCP头部:源端口: 随机端口目标端口: 1883序列号: x+n确认号: y+m标志: PSH, ACKMQTT数据:包类型: PUBLISH (3)剩余长度: 可变主题长度: 2字节长度前缀主题: 如"home/livingroom/led"包ID: 仅当QoS>0时出现有效载荷: 如"ON"或"OFF"
    

看到这些细节,你是不是更能理解MQTT的工作原理了?这些看似复杂的数据包,本质上就是设备之间传递的"便条",告诉对方"我想做什么"或"我已经做了什么"。

ESP32S3使用MQTT控制LED实践

是时候将理论付诸实践了!让我们使用ESP32S3通过MQTT协议来控制一个连接到IO9的LED。

硬件准备

  • ESP32S3开发板
  • LED(连接到IO9)
  • 220欧姆电阻
  • 连接线

软件准备

  • 安装Arduino IDE
  • 安装ESP32S3开发板支持
  • 安装PubSubClient库(用于MQTT通信)

代码实现

#include <WiFi.h>
#include <PubSubClient.h>// WiFi配置
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";// MQTT配置
const char* mqtt_server = "你的MQTT服务器地址";
const int mqtt_port = 1883;
const char* mqtt_client_id = "ESP32S3_LED_Controller";
const char* mqtt_topic = "home/esp32s3/led";// LED引脚
const int ledPin = 9;  // IO9WiFiClient espClient;
PubSubClient client(espClient);void setup_wifi() {delay(10);Serial.println("连接到WiFi...");WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("WiFi已连接");Serial.print("IP地址: ");Serial.println(WiFi.localIP());
}void callback(char* topic, byte* payload, unsigned int length) {// 将接收的字节数组转换为字符串String message;for (int i = 0; i < length; i++) {message += (char)payload[i];}Serial.print("收到消息: ");Serial.println(message);// 控制LEDif (message.equals("ON")) {digitalWrite(ledPin, HIGH);Serial.println("LED已打开");} else if (message.equals("OFF")) {digitalWrite(ledPin, LOW);Serial.println("LED已关闭");}
}void reconnect() {while (!client.connected()) {Serial.print("尝试MQTT连接...");if (client.connect(mqtt_client_id)) {Serial.println("已连接");// 订阅控制主题client.subscribe(mqtt_topic);} else {Serial.print("连接失败,错误码=");Serial.print(client.state());Serial.println(" 5秒后重试");delay(5000);}}
}void setup() {pinMode(ledPin, OUTPUT);Serial.begin(115200);setup_wifi();client.setServer(mqtt_server, mqtt_port);client.setCallback(callback);
}void loop() {if (!client.connected()) {reconnect();}// 处理MQTT消息client.loop();
}

实现分析

当我们运行这个程序时,ESP32S3会:

  1. 连接到WiFi网络
  2. 连接到MQTT服务器
  3. 订阅home/esp32s3/led主题
  4. 等待控制命令

当我们通过MQTT客户端(如MQTT Explorer或手机App)发布"ON"或"OFF"消息到home/esp32s3/led主题时,ESP32S3会接收到消息并相应地控制LED。

这个过程中发生的TCP和MQTT通信可以通过Wireshark捕获。发布"ON"消息时,我们将看到:

  1. MQTT PUBLISH包从发布者到MQTT服务器
  2. MQTT服务器将PUBLISH包转发给ESP32S3
  3. ESP32S3接收到PUBLISH包,解析内容,发现是"ON"
  4. ESP32S3控制IO9引脚输出高电平,点亮LED

这就像是我们在微信群(MQTT服务器)里发了一条消息"开灯",而ESP32S3正好在看这个群,看到消息后立即执行了开灯的动作!

MQTT的安全性考虑

在实际应用中,安全性至关重要。MQTT本身并不提供加密,但可以通过以下方式增强安全性:

  1. 使用MQTT over TLS/SSL:使用8883端口而不是标准的1883端口
  2. 客户端身份验证:使用用户名/密码或客户端证书
  3. 访问控制列表(ACL):在服务器端配置,限制客户端可以发布/订阅的主题

想象一下,这就像是给你的微信群设置了密码,并且限制了谁能发言、谁能看到消息。在物联网世界,这种保护措施不是可选的,而是必须的!

MQTT的高级特性

除了基本功能外,MQTT还有一些高级特性:

  1. 保留消息:服务器会保存标记为"保留"的消息,新订阅者连接时立即收到
  2. 遗嘱消息:客户端异常断开时自动发布的消息
  3. 共享订阅:多个客户端共享同一个订阅,实现负载均衡
  4. MQTT 5.0新特性:消息过期、主题别名、用户属性等

这些功能让MQTT变得更加强大和灵活。就像一个初看简单的瑞士军刀,打开后却发现它能完成各种意想不到的任务!

MQTT与其他协议的对比

为什么选择MQTT而不是其他协议?让我们做个对比:

特性MQTTHTTPCoAPAMQP
协议模型发布/订阅请求/响应请求/响应发布/订阅
消息开销极小中等
QoS级别0,1,2可靠/不可靠复杂QoS
适用场景低带宽网页应用资源受限企业消息

看到这个对比,你会发现MQTT在物联网场景中的优势多么明显!它就像是专为物联网"量身定制"的通信协议。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901758.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——反射、枚举以及lambda表达式

1. 反射 Java的反射&#xff08;reflection&#xff09;机制是在运⾏时检查、访问和修改类、接⼝、字段和⽅法的机制&#xff1b;这种动态获取信息以及动态调⽤对象⽅法的功能称为java语⾔的反射&#xff08;reflection&#xff09;机制。 用途 1. 框架开发 2. 注解处理 3.…

C语言教程(十):C 语言函数详解

一、引言 在 C 语言中&#xff0c;函数是一组执行特定任务的代码块。通过将复杂的程序逻辑划分为多个函数&#xff0c;不仅能提高代码的可读性、可维护性&#xff0c;还便于代码的复用。无论是简单的数学计算&#xff0c;还是复杂的系统操作&#xff0c;函数都发挥着核心作用。…

力扣面试150题--有效的字母异位词和字母异位词分组

Day 24 题目描述 思路 初次思路&#xff1a;如果两个字符串为异位词&#xff0c;说明它们长度相同并且字母出现的次数相同&#xff0c;于是有以下做法&#xff1a; 定义一个map&#xff0c;来保存s中每个字符的出现次数处理特殊情况&#xff0c;如果长度不同&#xff0c;直接…

数理逻辑(Mathematical Logic)综论与跨学科应用

李升伟 整理 数理逻辑&#xff08;Mathematical Logic&#xff09;是现代逻辑学与数学交叉的核心学科&#xff0c;以严格的数学方法研究逻辑推理的形式与规律。其发展深刻影响了数学基础、计算机科学、语言哲学等领域。以下从多个维度综论数理逻辑&#xff1a; 1. 核心分支 命…

高性能内存kv数据库Redis(续)

目录 四.主从同步与对象模型 1.Redis 淘汰策略 2.Redis 如何做到 持久化 2.1 redis为什么要实现持久化 2.2fork进程的写时复制机制 2.3大Key的影响 2.4redis做持久化的方式 2.5 aof 2.6 rdb 2.7 redis 持久化方式的优缺点 3.redis里面的高可用体现在哪里&#xff1f; 3.1r…

泛型算法——只读算法(一)

在 C 标准库中&#xff0c;泛型算法的“只读算法”指那些 不会改变它们所操作的容器中的元素&#xff0c;仅用于访问或获取信息的算法&#xff0c;例如查找、计数、遍历等操作。 accumulate std::accumulate()是 C 标准库**numeric**头文件中提供的算法&#xff0c;用于对序列…

SvelteKit 最新中文文档教程(21)—— 最佳实践之图片

前言 Svelte&#xff0c;一个语法简洁、入门容易&#xff0c;面向未来的前端框架。 从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte …

健康养生:开启活力生活的密钥

当我们在健身房看到年逾六旬却身形矫健的老人&#xff0c;在公园偶遇精神矍铄、步伐轻快的长者&#xff0c;总会惊叹于他们的健康状态。其实&#xff0c;这些都得益于长期坚持科学的养生之道。健康养生并非遥不可及的玄学&#xff0c;而是融入生活细节的智慧。​ 在饮食的世界…

Linux信号三部曲:产生机制、处理方式与内核接口

Linux系列 文章目录 Linux系列前言一、背景知识铺垫1.1 信号的基本概念1.2 进程对信号的处理 二、信号的产生2.1 前台进程和后台进程2.2 键盘组合键2.3 kill 命令2.4 系统调用2.4.1 signal()接口2.4.2 kill()接口2.4.3 raise()接口2.4.4 abort()接口 总结 前言 Linux中&#x…

win7/win10/macos如何切换DNS,提升网络稳定性

本篇教程教您如何在Windows10、Windows8.1、Windows7、MacOS操作系统切换DNS&#xff0c;以提升系统的稳定性&#xff0c;获得更好的操作体验。 Windows10及Windows8.1 1、右键单击“此计算机”&#xff0c;然后选择“属性”。进入Windows系统界面后&#xff0c;选择左侧的“…

移动硬盘突然打不开紧急救援指南:从排查到完整恢复‌

突发状况的典型特征‌ 当移动硬盘突然打不开时&#xff0c;用户常会遇到多种异常表现&#xff1a;接入电脑后硬盘指示灯虽亮但无法识别、系统反复提示“设备未连接成功”或弹出“磁盘结构损坏”的警告。部分情况下&#xff0c;资源管理器中的盘符虽可见&#xff0c;但双击后显示…

华为OD机试真题——统计匹配的二元组个数(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《统计匹配…

半导体制造如何数字化转型

半导体制造的数字化转型正通过技术融合与流程重构&#xff0c;推动着这个精密产业的全面革新。全球芯片短缺与工艺复杂度指数级增长的双重压力下&#xff0c;头部企业已构建起四大转型支柱&#xff1a; 1. 数据中枢重构产线生态 台积电的「智慧工厂4.0」部署着30万物联网传感器…

[Spark]深入解密Spark SQL源码:Catalyst框架如何优雅地解析你的SQL

本文内容组织形式 总结具体例子执行语句解析层优化层物理计划层执行层 猜你喜欢PS 总结 先写个总结&#xff0c;接下来会分别产出各个部分的源码解析&#xff0c;Spark SQL主要分为以下五个执行部分。 具体例子 接下来举个具体的例子来说明 执行语句 SELECT name, age FR…

【数据结构】4.单链表实现通讯录

在上一篇文章我们学会了用单链表来实现各种方法&#xff0c;在这一篇文章我们将在单链表的基础上实现通讯录。 0、准备工作 实现通讯录之前&#xff0c;我们还需要在单链表的基础上添加2个文件&#xff0c;头文件Contact.h和源文件Contact.c。Contact.c来实现通讯录方法的声明…

【bash】.bashrc

查看当前路径文件数量 alias file_num"ls -l | grep ^- | wc -l"查看文件大小 alias file_size"du -sh"alias ll alias ll"ls -ltrh"cd的同时执行ll alias cdcdls; function cdls() {builtin cd "$1" && ll }自定义prompt…

微信小程序实战案例 - 餐馆点餐系统 阶段 2 – 购物车

阶段 2 – 购物车&#xff08;超详细版&#xff09; 目标 把“加入购物车”做成 全局状态&#xff0c;任何页面都能读写在本地 持久化&#xff08;关闭小程序后购物车仍在&#xff09;新建 购物车页&#xff1a;数量增减、总价实时计算、去结算入口打 Git Tag v2.0‑cart 1. …

从红黑树到哈希表:原理对比与典型场景应用解析(分布式以及布隆过滤器)

在数据结构的世界里&#xff0c;红黑树一直以「自平衡二叉查找树」的身份备受赞誉。凭借红黑节点的精妙设计&#xff0c;它能将插入、删除、查找的时间复杂度稳定控制在 ( log ⁡ n ) (\log n) (logn)&#xff0c;成为处理有序数据的经典方案。然而&#xff0c;当业务场景对「…

游戏报错?MFC140.dll怎么安装才能解决问题?提供多种MFC140.dll丢失修复方案

MFC140.dll 是 Microsoft Visual C 2015 运行库的重要组成部分&#xff0c;许多软件和游戏依赖它才能正常运行。如果你的电脑提示 "MFC140.dll 丢失" 或 "MFC140.dll 未找到"&#xff0c;说明系统缺少该文件&#xff0c;导致程序无法启动。本文将详细介绍 …

《电子类专业:通往科技未来的钥匙》

一、电子类专业全景概览 在当今科技飞速发展的时代,电子类专业无疑占据着现代科技体系中基础与核心的重要地位。从我们日常生活中不可或缺的智能手机、电脑,到推动社会进步的人工智能、大数据技术,再到探索宇宙奥秘的航天航空设备,电子类专业的身影无处不在。它就像一把万…