05--MQTT物联网协议
一、MQTT的概念
MQTT 协议快速入门 2025:基础知识和实用教程 | EMQ
1.MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。

2.订阅与发布规则

二、MQTT 代理服务器

三、Mosquitto 代理服务器
Eclipse Mosquitto 也是一款开源的 MQTT Broker,兼容 MQTT 协议的 5.0、3.1.1 和 3.1 版本。Mosquitto 体积小巧,既可以运行在低功耗的单板计算机上,也可以部署在企业级服务器上。它采用 C 语言编写,可以用 C 库实现 MQTT 客户端。它支持 Windows、Mac、Linux 和 Raspberry Pi 等多种平台,为每个平台提供了方便安装的二进制文件。最新版本还增加了一个认证和授权插件 “mosquitto-go-auth”,以及一个用于管理 Mosquitto 实例的 Web 用户界面。此外,它还提供了一个 PHP 包装器 “Mosquitto-PHP”,可以方便地在 PHP 中开发 MQTT 客户端。
Eclipse Mosquitto 官方网站
GitHub - eclipse-mosquitto/mosquitto: Eclipse Mosquitto - An open source MQTT broker github开源网站
Mosquitto 服务器安装
1.下载 openssl 加密库源码
Old 1.1.1 Releases | OpenSSL Library

2.下载cjson 源码
GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C
3.下载mosquitto 服务器
Index of /files/source/

4.配置&安装⭐⭐
将下载好文件放到一个自己知道的路径,然后用wsl打开解压到家目录。不要解压到共享文件里。
------- openssl加密库安装---------
tar -xvf openssl-1.1.1q.tar.gz -C ~/ #1.解压源码
cd ~/openssl-1.1.1q/ #2.进入源码目录
./config #3.默认配置 make test -j12 #4.编译测试代码与库文件sudo make install #5.安装 ------cjson库安装-------cp cJSON-master.zip ~/ #1.拷贝到家目录cd ~/ #2.进入家目录sudo apt install unzip #3.安装解压工具 unzip cJSON-master.zip #4.解压json源码 cd cJSON-master/ #5.进入json源码make #6.编译源码sudo make install #7.安装 -----安装mosquitto代理服务器-----
sudo apt-get install g++ #1.安装g++编译器
tar -xvf mosquitto-2.0.9.tar.gz -C ~/ #2.解压到家目录
cd ~/mosquitto-2.0.9/ #3.进入源码目录
make #4.编译
sudo make install #5.安装 tip💡如果cjson库或ssl 库安装失败
cJSON - for client JSON output support. Disable with make WITH_CJSON=no Auto detected with CMake.make WITH_CJSON=no #去掉cjson openssl (libssl-dev on Debian based systems) - disable with make WITH_TLS=nomake WITH_TLS=no
测试成功如下

四、mosquitto 代理服务器使用
1、订阅与发布命令
#拷贝库文件到系统库中 sudo cp /usr/local/lib/lib* /lib#拷贝系统的配置文件 cp /etc/mosquitto/mosquitto.conf.example ./ //当前文件为自己写代码的文件里
2、修改端口

3、关闭防火墙

#开启代理服务器 尝试能不能行mosquitto -c ./mosquitto.conf.example#订阅主题 'test/topic' mosquitto_sub -t 'test/topic' -v#发布消息 mosquitto_pub -t 'test/topic' -m 'hello world'

4、发布端函数接口
将官方大的代码拷贝到自己写代码的文件里边看官方代码边写自己的代码。

//1初始化MQTT库,在调用任何函数之前必须要调用该函数
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.//2创建一个新的客户端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客户端ID,如何为NULL ,系统自动分配一个ID,且clean_session参数必须为 true
clean_session: true 代理服务器在客户端断开后会清除数据 false 代理服务器在客户端断开后会保留数据
obj:传递给回调函数的参数
返回值:成功 客户端对象地址 失败 NULL //3连接MQTT服务器
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客户端对象
host:服务器IP地址
port:服务器端口号 👉1883
keepalive:保持连续ping 包,设置一段时间后发送一个ping给服务器
返回值: MOSQ_ERR_SUCCESS - on success.//4启动网络线程,不断处理网络数据
int mosquitto_loop_start(struct mosquitto *mosq);
mosq:客户端对象
返回值: MOSQ_ERR_SUCCESS - on success.//5⭐重点,难点 : 发布消息
int mosquitto_publish(struct mosquitto *mosq, //客户端对象 int *mid, //消息ID ,设置为 NULL 即可const char *topic, //👍发布的消息主题int payloadlen, //发布消息长度 between 0 and 268,435,455.const void *payload, //发布的消息int qos, //👍消息质量 0 ,1 , 2bool retain); //消息保留标记为 true 保留消息
qos 消息质量
MQTT(Message Queuing Telemetry Transport)协议定义了三种消息质量等级(QoS),以确保在不同场景下消息的可靠传输。
以下是三种QoS级别的详细说明:
1. QoS 0(At Most Once,最多一次)
特点:消息最多被传递一次,没有确认机制,消息可能会丢失或重复。
适用场景:适用于对消息完整性要求不高的场景,如天气更新、实时数据流、传感器数据等。在这些场景中,即使消息丢失或重复,也不会造成重大影响。
传输过程:发送方发送消息后,不等待接收方的确认,也不存储消息以进行重传。
2. QoS 1(At Least Once,至少一次)
特点:消息至少被传递一次,但可能会出现重复的消息。
适用场景:适用于对消息丢失敏感,但对重复不敏感的场景,如传感器数据、开关状态同步等。在这些场景中,确保消息到达比避免重复更重要。
传输过程:发送方发送消息后,会等待接收方的确认报文(PUBACK)。如果未收到确认,发送方会重传消息。接收方收到消息后,会发送PUBACK确认报文。
3. QoS 2(Exactly Once,仅一次)
特点:消息确保只传递一次,没有重复。这是最高级别的QoS,适用于对消息的完整性和顺序性要求非常高的场景。
适用场景:适用于金融交易、关键命令等场景,在这些场景中,消息的丢失或重复都是不可接受的。
传输过程:发送方和接收方通过四次握手过程(PUBREC、PUBREL、PUBCOMP)来确保消息只被接收一次。发送方发送消息后,等待接收方的PUBREC确认,然后发送PUBREL,最后等待接收方的PUBCOMP确认。
QoS级别的选择
QoS 0:适用于实时性要求高,但对数据丢失和重复容忍度较高的场景。
QoS 1:适用于需要确保消息至少被接收一次,但允许重复的场景。
QoS 2:适用于需要确保消息仅被接收一次,且对实时性要求不高的场景。
注意事项
网络条件:在网络条件较差的情况下,建议选择较低的QoS级别,以减少消息丢失的风险。
系统资源:QoS级别越高,传输过程的复杂程度和系统资源消耗也越大。
综上所述,根据具体的应用场景和需求选择合适的QoS级别,可以在确保消息可靠传输的同时,优化系统性能和资源利用率。
⭐⭐发布端代码例子:
#include <mosquitto.h> //⚠️声明MQTT库的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc, char *argv[])
{// 1.初始化MQTT库mosquitto_lib_init();// 2.创建一个客户端struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);if (mosq == NULL){perror("创建客户端失败\n");return 1;}else{printf("创建客户成功\n");}// 3.连接服务器,超时设置为60秒int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);if (ret != MOSQ_ERR_SUCCESS){perror("连接服务器失败\n");return 1;}else{printf("连接服务器成功\n");}// 4.启动网络线程mosquitto_loop_start(mosq);while (1){printf("请输入发布的主题和消息\n");char topic[50] = {0};char payload[268] = {0};scanf("%s %s", topic, payload);int ret = mosquitto_publish(mosq, NULL, topic, strlen(payload), payload, 0, false);if (ret != MOSQ_ERR_SUCCESS){perror("发布消息失败\n");return 1;}else{printf("发布消息成功\n");}}mosquitto_destroy(mosq); //销毁对象mosquitto_lib_cleanup(); //清空函数库
}
5、订阅端函数接口

//1.初始化MQTT库,在调用任何函数之前必须要调用该函数
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.//2。创建一个新的客户端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客户端ID,如何为NULL ,系统自动分配一个ID,且clean_session参数必须为 true
clean_session: true 代理服务器在客户端断开后会清除数据 false 代理服务器在客户端断开后会保留数据
obj:传递给回调函数的参数
返回值:成功 客户端对象地址 失败 NULL //3.连接MQTT服务器
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客户端对象
host:服务器IP地址
port:服务器端口号 👉1883
keepalive:保持连续ping 包,设置一段时间后发送一个ping给服务器 (超时时间)
返回值: MOSQ_ERR_SUCCESS - on success.//4.订阅主题
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos);
mosq:客户端对象
mid:消息ID,设置为NULL不关心
sub:👍需要订阅的主题
qos:消息质量 0,1,2
返回值: MOSQ_ERR_SUCCESS - on success.//5.⭐重点,难点:设置消息回调函数,当订阅的主题有消息时,会调用该函数
void mosquitto_message_callback_set(struct mosquitto *mosq,
void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *));
mosq:客户端对象
on_message:函数指针,指向一个回调函数如下👇
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{/* This blindly prints the payload, but the payload can be anything so take care. */printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}
mosq:客户端对象
obj:创建客户端时传递的参数
msg:👍消息💡消息结构体
struct mosquitto_message{int mid; //发布消息id char *topic; //主题void *payload; //消息 int payloadlen; //消息长度 int qos; //通信质量 bool retain; //保留消息标记
};6.循环接收消息 int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets);mosq:客户端对象 timeout:超时检测 ,设置 -1 永久等待
订阅端代码例子:
#include <mosquitto.h> //⚠️声明MQTT库的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{/* This blindly prints the payload, but the payload can be anything so take care. */printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}int main(int argc, char *argv[])
{// 1.初始化MQTT库mosquitto_lib_init();// 2.创建一个客户端struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);if (mosq == NULL){perror("创建客户端失败\n");return 1;}else{printf("创建客户成功\n");}// 3.连接服务器int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);if (ret != MOSQ_ERR_SUCCESS){perror("连接服务器失败\n");return 1;}else{printf("连接服务器成功\n");}// 4.订阅一个主题ret = mosquitto_subscribe(mosq, NULL, "test", 0);if (ret != MOSQ_ERR_SUCCESS){perror("订阅失败\n");return 1;}else{printf("订阅成功\n");}// 5.设置消息回调函数mosquitto_message_callback_set(mosq, on_message); // 设置接收消息回调函数// 6.循环接收消息mosquitto_loop_forever(mosq, -1, 1); // 一直循环接收数据mosquitto_destroy(mosq);mosquitto_lib_cleanup();return 0;
}
五、MQTTX 调试助手
公共测试服务器:免费的公共 MQTT 服务器 | EMQ
MQTTX 下载

安装

设置为简体中文

主题的订阅与发布调试
1.新建链接:服务器为你写代码的地址。

2.主题订阅:主题名字随便

3.主题发布,要跟代码的订阅一样。

4.实现MQTT远程通信
即在调试助手中(发送端)发送消息到阿里云(部署MQTT代理服务器)中,然后MQTT代理服务器转换到Ubuntu的终端中。

相关文章:
05--MQTT物联网协议
一、MQTT的概念 MQTT 协议快速入门 2025:基础知识和实用教程 | EMQ 1.MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它…...
学习设计模式《二》——外观模式
一、基础概念 1.1、外观模式的简介 外观模式的本质是【封装交互、简化调用】; 外观模式的说明:就是通过引入一个外观类,在这个类里面定义客户端想要的简单方法,然后在这些方法里面实现;由外观类再去分别调用内部的多个…...
永磁同步电机控制算法-VF控制
一、原理介绍 V/F 控制又称为恒压频比控制,给定VF 控制曲线 电压是频率的tt例函数 即控制电压跟随频率变化而变化以保持磁通恒定不变。 二、仿真模型 在MATLAB/simulink里面验证所提算法,搭建仿真。采用和实验中一致的控制周期1e-4,电机部分计算周期为…...
qt 配置 mysql 驱动问题:Cannot load library qsqlmysql;QMYSQL driver not loaded
项目场景: 环境版本: qt :5.14.2 mysql:8.0 windows:10 提示:qt 配置 mysql 驱动: 项目场景:qt 配置 mysql 驱动 问题描述 提示:这里描述项目中遇到的问题:…...
MyBatis-Plus 实战:优雅处理 JSON 字段映射(以 JSONArray 为例)
🎯MyBatis-Plus 实战:优雅处理 JSON 字段映射(以 JSONArray 为例) 👨💻 作者:William Dawson |📅 更新日期:2025-04-21 🚀 标签:MyB…...
线性代数 | 知识点整理 Ref 2
注:本文为 “线性代数 | 知识点整理” 相关文章合辑。 因 csdn 篇幅合并超限分篇连载,本篇为 Ref 2。 略作重排,未整理去重。 图片清晰度限于引文原状。 如有内容异常,请看原文。 【数学】线性代数知识点总结 阿巴 Jun 于 2024-…...
PyTorch深度学习框架60天进阶学习计划 - 第47天:模型压缩蒸馏技术(一)
PyTorch深度学习框架60天进阶学习计划 - 第47天:模型压缩蒸馏技术(一) 第一部分:知识蒸馏的温度调节机制详解 欢迎来到我们学习计划的第47天!今天我们将深入探讨模型压缩技术中的两个重要方法:知识蒸馏和…...
华为OD机试真题——最小的调整次数/特异性双端队列(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《最小的调…...
java+postgresql+swagger-多表关联insert操作(九)
入参为json,然后根据需要对多张表进行操作: 入参格式: {"username": "车主01","usertel": "11111111111","useridtype": "2","useridcard": null,"proname&qu…...
[密码学基础]国密算法深度解析:中国密码标准的自主化之路
国密算法深度解析:中国密码标准的自主化之路 国密算法(SM系列算法)是中国自主研发的密码技术标准体系,旨在打破国际密码技术垄断,保障国家信息安全。本文将从技术原理、应用场景和生态发展三个维度,全面解…...
Flink-01学习 介绍Flink及上手小项目之词频统计
flink简介 官网 概述: 学习Flink具体包括四个关键概念:流数据的持续处理,事件时间,有状态流处理和状态快照。 Apache Flink 是一个开源的流处理框架,旨在处理批处理和实时数据处理,具有高吞吐量和低延迟的…...
自注意力机制、多头自注意力机制、填充掩码 Python实现
原理讲解 【Transformer系列(2)】注意力机制、自注意力机制、多头注意力机制、通道注意力机制、空间注意力机制超详细讲解 自注意力机制 import torch import torch.nn as nn# 自注意力机制 class SelfAttention(nn.Module):def __init__(self, input…...
目标检测篇---R-CNN梳理
目标检测系列文章 第一章 R-CNN 目录 目标检测系列文章📄 论文标题🧠 论文逻辑梳理1. 引言部分梳理 (动机与思想) 📝 三句话总结🔍 方法逻辑梳理🚀 关键创新点🔗 方法流程图补充边界框回归 (BBR)1. BBR 的…...
C#处理网络传输中不完整的数据流
1、背景 在读取byte数组的场景(例如:读取文件、网络传输数据)中,特别是网络传输的场景中,非常有可能接收了不完整的byte数组,在将byte数组转换时,因字符的缺失/增多,转为乱码。如下…...
HTML 初识
段落标签 <p><!-- 段落标签 -->Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugiat, voluptate iure. Obcaecati explicabo sint ipsum impedit! Dolorum omnis voluptas sint unde sed, ipsa molestiae quo sapiente quos et ad reprehenderit.&l…...
MATLAB 训练CNN模型 yolo v4
学生对小车控制提出了更好的要求,能否加入深度学习模型。 考虑到小车用matlab来做,yolo v5及以上版本都需要在pytorch下训练,还是用早期版本来演示。 1 yolov4 调用 参考 trainYOLOv4ObjectDetector (mathworks.com) name "tiny-yo…...
【前端】跟着maxkb学习logicflow流程图画法
文章目录 背景1. 选定学习对象-maxkb应用逻辑编排2. 确定实现框架3. 关键逻辑:查看app-node.js4. 学习开始节点绘制流程数据形式 5. 给节点增加表单输入框遇到过的问题 背景 看看前端如何绘制流程图,界面好看点。 "logicflow/core": "1.…...
数据结构-C语言版本(八)字符串
数据结构中的字符串:概念、操作与实战 第一部分 字符串的分类及常见形式 字符串是由零个或多个字符组成的有限序列,是编程中最基础也最重要的数据结构之一。 1. C语言中的字符串表示 字符数组形式 char str1[10] {H, e, l, l, o, \0};字符串字面量…...
Arduino示例代码讲解:Project 07 - Keyboard 键盘
Arduino示例代码讲解:Project 07 - Keyboard 键盘 Project 07 - Keyboard 键盘程序功能概述功能:硬件要求:输出:代码结构全局变量`setup()` 函数`loop()` 函数读取电位器值:打印电位器值:播放音调:运行过程注意事项Project 07 - Keyboard 键盘 /*Arduino Starter Kit e…...
oracle expdp/impdp 用法详解
oracle expdp/impdp 用法详解 创建逻辑目录,该命令不会在操作系统创建真正的目录,最好以system等管理员创建。 create directory db_bak as d:\test\dump; 查看管理理员目录(同时查看操作系统是否存在,因为Oracle并不关心该目录是…...
【漏洞复现】CVE-2024-38856(ApacheOfbiz RCE)
【漏洞复现】CVE-2024-38856(ApacheOfbiz RCE) 1. 漏洞描述 Apache OFBiz 是一个开源的企业资源规划(ERP)系统。它提供了一套企业应用程序,用于集成和自动化企业的许多业务流程。 这个漏洞是由于对 CVE-2023-51467 的…...
超详细VMware虚拟机扩容磁盘容量-无坑版
1.环境: 虚拟机:VMware Workstation 17 Pro-17.5.2 Linux系统:Ubuntu 22.04 LTS 2.硬盘容量 虚拟机当前硬盘容量180G -> 扩展至 300G 3.操作步骤 (1)在虚拟机关机的状态下,虚拟机硬盘扩容之前必…...
每日一题算法——移除链表元素、反转链表
移除链表元素 力扣题目链接 我的解法: 注意细节:要删掉移除的元素。 class Solution { public:ListNode* removeElements(ListNode* head, int val) {while(head!nullptr){if(head->valval){headhead->next;}}ListNode* nowhead head;while(n…...
全面理解Linux 系统日志:核心文件与查看方法
全文目录 1 Linux 系统日志分类及功能1.1 通用日志1.1.1 /var/log/messages1.1.2 /var/log/syslog 1.2 安全相关日志1.2.1 /var/log/auth.log(Debian/Ubuntu)或 /var/log/secure(RHEL/CentOS)1.2.2 /var/log/audit/au…...
机器学习-08-关联规则更新
总结 本系列是机器学习课程的系列课程,主要介绍机器学习中关联规则和协同过滤。 参考 机器学习(三):Apriori算法(算法精讲) Apriori 算法 理论 重点 【手撕算法】【Apriori】关联规则Apriori原理、代码…...
Flutter与FastAPI的OSS系统实现
作者:孙嘉成 目录 一、对象存储 二、FastAPI与对象存储 2.1 缤纷云S4服务API对接与鉴权实现 2.2 RESTful接口设计与异步路由优化 三、Flutter界面与数据交互开发 3.1 应用的创建 3.2页面的搭建 3.3 文件的上传 关键词:对象存储、FastAPI、Flutte…...
Kubernetes控制平面组件:API Server详解(二)
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
MySQL-锁机制3-意向共享锁与意向排它锁、死锁
文章目录 一、意向锁二、死锁应该如何避免死锁问题? 总结 一、意向锁 在表获取共享锁或者排它锁时,需要先检查该表有没有被其它事务获取过X锁,通过意向锁可以避免大量的行锁扫描,提升表获取锁的效率。意向锁是一种表级锁…...
报告系统状态的连续日期 mysql + pandas(连续值判断)
本题用到知识点:row_number(), union, date_sub(), to_timedelta()…… 目录 思路 pandas Mysql 思路 链接:报告系统状态的连续日期 思路: 判断连续性常用的一个方法,增量相同的两个列的差值是固定的。 让日期与行号 * 天数…...
pytest自动化中关于使用fixture是否影响用例的独立性
第一个问题:难道使用fixture 会影响用例独立吗? ✅ 简单回答: 使用 fixture ≠ 不独立。 只要你的 fixture 是每次测试都能自己运行、自己产生数据的,那么测试用例依然是“逻辑独立”的。 ✅ 怎么判断 fixture 是否影响独立性&a…...
