Qt与MQTT交互通信
MQTT全称是(Message Queuing Telemetry Transport),即消息队列遥测传输协议
是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,并且该协议构建于TCP/IP协议之上,常用于互联网中,轻便

基本组件
-
客户端(Client):
- 任何设备(传感器、手机、应用程序等)都可以作为MQTT客户端。
- 客户端可以发布消息(Publisher)或者订阅消息(Subscriber)。
-
代理(Broker):
- 代理是MQTT网络的核心组件,负责接收来自发布者的消息并将其转发给订阅了该主题的客户端。
- 它确保消息的传递和分发,管理客户端连接、订阅、注销等操作。
工作流程
-
连接:
- MQTT客户端通过TCP/IP与MQTT代理建立连接。连接建立后,客户端必须发送“连接”请求。
- 代理根据请求的信息(如客户端ID、用户名、密码等)进行身份验证和授权。
-
发布(Publish):
- 客户端将消息发布到特定的主题(Topic)。主题是一种类似路径的层级结构,可以用斜杠(/)分隔,如
sensors/temperature/kitchen。 - 代理接收消息并进行处理。
- 客户端将消息发布到特定的主题(Topic)。主题是一种类似路径的层级结构,可以用斜杠(/)分隔,如
-
订阅(Subscribe):
- 客户端可以订阅一个或多个主题。订阅后,代理会将所有属于该主题的消息分发给相应的客户端。
- 订阅可以是精确的主题,也可以包含通配符来匹配多个主题。
-
消息分发:
- 代理将发布的消息转发给所有订阅了该主题的客户端。
-
断开连接:
- 客户端可以随时断开与代理的连接。代理也可以在检测到长时间未活动后断开客户端连接。
应用场景
MQTT广泛应用于物联网、车联网、智能家居、远程监控和消息推送等场景。其轻量级、低带宽、高效的特性使其特别适合资源受限及网络不稳定的环境。
通过这些组件和操作,MQTT可以实现高效、可靠的消息传递,成为物联网通信中的重要协议。
QT 交互例子
准备工作:MQTT客户端的交互需要安装MQTT代理,及代理服务器,负责将消息转发。按照好后配置相关,如监听的端口和协议、是否启用消息持久化、日志文件路径等。根据需求修改这些设置,保存配置文件等。这里就不赘述

接下来详细讲解在QT中MQTT的使用:
1.使用官方的MQTT源码,造好的轮子有用就用,官网:https://github.com/emqx/qmqtt
或者这个链接下载: https://pan.baidu.com/s/1oUtl9R628-3cfS-tyL6iEQ?pwd=1234 提取码: 1234
下载完解压:放到程序目录下
我的例子程序结构如下,分为mqtt封装的库,用于发送接收消息,和界面主程序用于控制发送和消息显示

2.写一个例子,这里给关键代码展示
一是连接mqtt,二是推送消息函数,三是接收订阅的消息函数
void MqttShareHandle::initMqtt()
{if (client) {return;}client.reset(new QMqttClient);QObject::connect(client.get(), &QMqttClient::connected, this, &MqttShareHandle::connected);QObject::connect(client.get(), &QMqttClient::disconnected, this, &MqttShareHandle::disconnected);QObject::connect(client.get(), &QMqttClient::errorChanged, this, &MqttShareHandle::errorChanged);QObject::connect(client.get(), &QMqttClient::messageReceived, this,[=](const QByteArray &message, const QMqttTopicName &topic) {emit messageReceived(message, topic.name());});QObject::connect(client.get(), &QMqttClient::messageReceived, this,[=](const QByteArray &message, const QMqttTopicName &topic) {onMessageReceived(message, topic.name());});
}void MqttShareHandle::connectToHost(const QString &host,quint16 port,const QString &username,const QString &password)
{if (!client || isConnected()) {return;}client->setHostname(host);client->setPort(port);client->setUsername(username);client->setPassword(password);client->connectToHost();
}
//订阅消息
void MqttShareHandle::subscribeBizTopics()
{//保证消息至少到达一次。//较为可靠,适用于大多数需要保证消息到达的场景const quint8 qos = 1;subscribeTopic(TopicAppEnvData, qos);subscribeTopic(TopicAppDeviceStatus, qos);subscribeTopic(TopicAppEventNotify, qos);
}bool MqttShareHandle::subscribeTopic(const QString &topic, quint8 qos)
{if (!client) {return false;}auto subscription = client->subscribe(topic, qos);return subscription ? subscription->state() == QMqttSubscription::Subscribed : false;
}//推送消息
bool MqttShareHandle::publishTopic(const QString &topic, const QByteArray &data, quint8 qos, bool retain)
{if (!client) {return false;}emit printMsg(QString("推送消息, topic:%1,data:%2").arg(topic).arg(QString(data)));auto ret = client->publish(topic, data, qos, retain);return ret != -1;
}void MqttShareHandle::onMessageReceived(const QByteArray &message, const QString &topic)
{QJsonParseError error;QJsonDocument doc = QJsonDocument::fromJson(message, &error);if (error.error != QJsonParseError::NoError) {return;}//QMetaObject::invokeMethod(this, MessageMap.value(topic).toUtf8(), Q_ARG(QByteArray,message));emit printMsg(QString("收到消息推送, topic:%1,data:%2").arg(topic).arg(QString(message)));if(topic == TopicAppEnvData) {emit appEnvDataUpdate(message);}else if(topic == TopicAppEventNotify) {emit appEventNotify(message);}else if(topic == TopicAppDeviceStatus) {emit appDeviceStatusUpdate(message);}
}
我的这个例子用了五个主题要演示推送和接收
// 环境信息更新主题
QString MqttShareHandle::TopicAppEnvData = "/Topic/EnvData";
// 设备状态更新主题
QString MqttShareHandle::TopicAppDeviceStatus = "/Topic/DeviceStatus";
// 事件通知主题
QString MqttShareHandle::TopicAppEventNotify = "/Topic/EventNotify";
//------------------------消息发布(推送)-------------------------
// 控制设备主题
QString MqttShareHandle::TopicControlDevice = "/Topic/ControlDevice";
// 控制门主题(开关门)
QString MqttShareHandle::TopicControlDoor = "/Topic/ControlDoor";
写了一个demo程序,如下,改程序可以通过mqtt推送开关门控制事件,模拟控制订阅“TopicControlDoor”主题的设备控制开关门,控制订阅TopicControlDevice主题的设备控制开关灯,并且订阅相关设备推送消息的主题,便于接收响应的信息


演示下效果,比较简陋,:
我用这个QT客户端模式外部设备

演示视频
通过订阅环境主题,事件,设备状态,可以接收设备的相关消息推送
设备也订阅了控门事件,控灯事件。接收到app的推送后,也显示出来,做出相应的处理

通过这个例子,可以认识到,mqtt的通讯方式是一对多,也可以一对一,实现方式也很简单,订阅与发布。
订阅就相当于你关注了一个人,UP主(uploader),他要是发布了动态或者视频等,就会通知你,如果你没有关注那个人,肯定不会接收到通知
发布就反过来,你是UP主,发布的东西只要他人关注了你,就会被通知
这个例子的源码我就放在这里了,有什么不懂的,欢迎评论区交流哈!
链接: https://pan.baidu.com/s/1v_xViXSHoV2QekwdKDq7SA?pwd=6666 提取码: 6666
为什么有了tcp通信后,还要有人写一个mqtt出来呢?
mqtt的优势
1. 发布/订阅模式
MQTT 采用发布/订阅模式,允许客户端发布消息到主题(Topic),其他客户端可以订阅这些主题来接收消息。这种模式使得消息的传递更加灵活和解耦,客户端之间不需要直接连接,减少了复杂性。
2. 轻量级
MQTT 协议设计得非常轻量级,适合在带宽有限、网络不稳定的环境中使用,如物联网设备。MQTT 的消息头非常小,最小只有 2 字节,这使得它在低带宽网络中传输效率更高。
3. QoS(服务质量)
MQTT 提供了三种服务质量(QoS)级别:
- QoS 0:最多一次(At most once),消息发送一次,不保证接收。
- QoS 1:至少一次(At least once),消息至少发送一次,可能会重复。
- QoS 2:恰好一次(Exactly once),消息只发送一次,保证不重复。
QoS 0(最多一次,At most once)
特点:
- 消息传输是尽力而为,不保证消息到达。
- 不进行消息确认,不做重发。
- 最低的网络开销和延迟。
使用场合:
- 传感器数据:如环境温度、湿度等,定期发送,如果丢失一两条数据不会有太大影响。
- 日志数据:实时性和完整性要求不高的日志信息。
- 状态更新:如设备的在线状态,定期发送,如果有丢失可在下次更新时弥补。
优点:
- 最低的网络开销。
- 最低的延迟。
- 简单实现。
缺点:
- 不保证消息到达。
- 可能会丢失消息。
QoS 1(至少一次,At least once)
特点:
- 消息至少到达一次。
- 发送者会重发消息直到收到接收者的确认。
- 接收者可能会收到重复的消息,需要去重。
使用场合:
- 重要数据:如报警信息,需要确保接收者至少收到一次,即使可能会有重复。
- 财务记录:如银行交易,需要确保消息到达,但可以接受重复处理。
- 设备控制:如远程设备控制命令,需要确保命令被接收和执行,但可以手动处理重复执行。
优点:
- 保证消息至少到达一次。
- 较为可靠,适用于大多数需要保证消息到达的场景。
缺点:
- 可能会收到重复消息,需要处理冗余。
- 网络开销和延迟高于 QoS 0。
QoS 2(只有一次,Exactly once)
特点:
- 消息保证到达且仅到达一次。
- 通过四次消息交换确保消息的唯一性和可靠性。
- 最高的可靠性,适合对传输可靠性要求极高的场合。
使用场合:
- 关键指令:如关键操作的执行命令,不能出现丢失或重复的情况。
- 交易处理:如金融交易,需要严格的消息确保机制,要求高可靠性。
- 数据同步:如重要数据库的同步操作,需要确保数据准确性和一致性。
优点:
- 保证消息仅到达一次。
- 最高的传输可靠性。
缺点:
- 最高的网络开销。
- 延迟较高,因为需要多次消息交换。
- 实现复杂。
这些 QoS 级别使得 MQTT 能够适应不同的应用场景,确保消息的可靠传输。
4. 会话保持
MQTT 支持会话保持(Session Persistence),即使在客户端断开连接后,服务器仍然可以保存客户端的订阅信息和未接收的消息,当客户端重新连接时,可以继续接收这些消息。
5. 遗嘱消息(Last Will and Testament)
MQTT 支持遗嘱消息(LWT),客户端可以在连接时设置一个遗嘱消息,当客户端异常断开连接时,服务器会自动发布这个遗嘱消息,通知其他客户端该客户端已经断开连接。
6. 心跳机制
MQTT 支持心跳机制(Keep Alive),客户端可以定期发送 PING 请求,确保连接的活跃性,服务器也可以通过 PING 响应来检测客户端的连接状态。
7. 安全性
MQTT 支持 TLS/SSL 加密,确保消息在传输过程中的安全性。此外,MQTT 还支持用户名和密码认证,增加了系统的安全性。
8. 易于扩展
MQTT 的发布/订阅模式和主题(Topic)结构使得系统易于扩展。新的客户端可以轻松地加入系统,订阅感兴趣的主题,而不需要修改现有的客户端或服务器。
9. 广泛支持
MQTT 协议得到了广泛的支持,有大量的客户端库和服务器实现,适用于各种编程语言和平台,如 C、C++、Java、Python、JavaScript 等。
总结
相比于直接使用 TCP,MQTT 提供了更高层次的抽象和功能,使得消息的传递更加灵活、可靠和高效。特别是在物联网和低带宽网络环境中,MQTT 的优势更加明显。
相关文章:
Qt与MQTT交互通信
MQTT全称是(Message Queuing Telemetry Transport),即消息队列遥测传输协议 是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,并且该协议构建于TCP/IP协议之上,常用于互联网中&am…...
dd 命令:复制和转换文件
一、dd 命令简介 dd 命令是一个在 Unix 和类 Unix 系统中用于复制文件和转换文件的命令行工具。它的功能非常强大,可以用于各种目的,例如创建镜像文件、备份和恢复数据、复制数据等。 dd 是一个用于读取、转换和写入数据的工具,通常…...
文件系统(磁盘 磁盘文件 inode)
文章目录 磁盘看看物理磁盘磁盘的存储结构 对磁盘的储存进行逻辑抽象inode号文件名 -> inode判断文件在哪个分区 磁盘 电脑中存在非常多的文件,被打开的文件只是少量的。 没有被打开的文件,在磁盘中放着,那么文件是如何存取? …...
ThreeJs创建圆环
ThreeJs除了创建基本的长方体,球形,圆柱等几何体,也可以创建一些特殊的几何体,比如圆环,多边体,这节就来讲怎么用Threejs绘制出圆环。首先依然是要创建出基础的组件,包括场景,相机&a…...
React实现类似Vue的路由监听Hook
React实现类似Vue的路由监听Hook 监听路由变化;React Hook封装,返回回调函数,新旧路由为函数参数; 代码 import { useEffect, useRef } from react; import { useHistory, useLocation } from react-router-dom;/*** 监听路由变…...
Visual Studio打开项目的一些小技巧
Visual Studio(VS)是一款功能强大的集成开发环境,许多刚入门C/C的小白也会使用这款软件进行写代码,然而它的操作并不简单,下面将讲解一下VS打开项目文件的一些小技巧。 目录 🎁创建空项目 ❤️①点击“创建新项目” ❤️②点击“…...
前端页面中使用 ppt 功能,并且可以随意插入关键帧
要在前端页面中实现类似 PowerPoint 的功能,并且能够随意插入和控制关键帧动画,你可以使用 HTML、CSS 和 JavaScript 结合的方式来创建一个互动幻灯片系统。以下是一个详细的实现方案,包括如何插入和控制关键帧动画: 1. 基础 HTM…...
机器学习:opencv--图像金字塔
目录 一、图像金字塔 1.图像金字塔是什么? 2.有哪些常见类型? 3.金字塔的构建过程 4.图像金字塔的作用 二、图像金字塔中的操作 1.向下采样 2.向上采样 3.注意--无法复原 三、代码实现 1.高斯金字塔向下采样 2.高斯金字塔向上采样 3.无法复…...
linux安全软件Hydra使用教程
Hydra 是一个强大的网络登录工具,常用于渗透测试,支持对多种服务和协议(如 SSH、FTP、HTTP 等)进行暴力crack攻击。它可以通过字典攻击来测试用户名和密码的有效性。以下是关于如何使用 Hydra 的基本步骤和示例: 1. 安…...
【ShuQiHere】从晶体管到逻辑门:数字电路的构建之旅
【ShuQiHere】 现代计算机和电子设备的基础是逻辑电路(Logic Circuits),它们执行信息处理和运算任务。在这些电路的核心,是晶体管(Transistors) 和 逻辑门(Logic Gates)。通过理解这…...
PDF扫描版文字识别OCR
PDF扫描版文字识别OCR 最近需要有对PDF扫描版进行文字可识别的需求,这里介绍一款工具挺好用的 这是一款开源的OCR工具 github地址 https://github.com/hiroi-sora/Umi-OCR 主要功能及特点 免费:本项目所有代码开源,完全免费。方便&#…...
Synchronized由什么样的缺陷? Java Lock是怎么弥补这些缺陷的?
synchronized 的缺陷 Synchronized 在 Java 中是最基础的线程同步机制,尽管简单易用,但也存在一些缺陷和局限性: 性能开销: synchronized 内部实现的监视器锁可能导致不必要的线程上下文切换和频繁竞争,从而引起性能下…...
联合仿真(FMI,FMU)资料收集
本文地址:https://blog.csdn.net/t163361/article/details/142262888 最近在研究使用Unity导入FMU模块进行仿真的功能。做功能前先尽可能收集下资料。 FMI标准 官方网站 github标准库 FMI标准由Modelica协会主导,具体介绍 FMI目前有三个标准 FMI1:20…...
Android Radio2.0——动态列表回调(七)
上一篇文章我们主要介绍了电台动态列表的获取流程,这里我们主要处理对应的回调流程以及扫描流程。 1)通过 getDynamicProgramList() 方法获取动态列表。 2)按照动态列表的内容,循环调用 scan() 方法执行向上调台,直到列表中的内容搜索完成。 3)根据 RadioManager.Program…...
在conda虚拟环境中安装cv2(试错多次总结)
首先保证你创建好了虚拟环境,并在anaconda命令窗口激活虚拟环境 依次输入下列命令: pip install opencv-python3.4.1.15 pip install opencv-contrib-python3.4.1.15 pip install dlib19.6.1 然后测试cv2是否可以使用,输入python 运行pyth…...
【EI稳定,马来亚大学主办】2024年计算机与信息安全国际会议(WCCIS 2024,9月27-29)
2024年计算机与信息安全国际会议 (WCCIS 2024) 将于2024年9月27-29日召开。 会议旨在为从事计算机与信息安全的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术,了解学术发展趋势,拓宽研究思路,加强学术研究和探讨&…...
免费AI播客生成:notebooklm可以生成播客的两个发言人谈论的内容,从各种来源如研究论文、文章
参考: https://notebooklm.google.com/ 可以上传文章链接,ai自动生成播客两人对话: 另外notebooklm他本身也是个rag知识库对话,可以直接聊天框对话...
“MIME 媒体类型“用来标识网络传输内容的格式标准
MIME 类型(Multipurpose Internet Mail Extensions 类型),也称为媒体类型,是用来标识网络传输内容的格式的标准。这些类型帮助 Web 服务器和浏览器理解如何处理和显示数据。MIME 类型在 Web 开发和网络通信中起着关键作用…...
MySql的基础讲解
一、初识MySql 数据库:按照数据结构来组织、存储和管理数据的仓库;是一个长期存储在计算机内的、有组织的、可共享 的、统一管理的大量数据的集合; OLTP:联机事务处理,主要是对数据库的增删改查。 OLTP 主要用来记录…...
类型转换等 面试真题
题目1 请问哪个结果为NaN A. 123null B. 123‘1’ C. 123/0 D. 123undefined 在这四个表达式中,只有D. 123 undefined 的结果是 NaN,原因如下: A. 123 null 结果是:123原因:null 在数值运算中会被自动转换为 0&a…...
BouncyCastle.NET证书管理完全教程:生成、验证与撤销的终极指南 [特殊字符]
BouncyCastle.NET证书管理完全教程:生成、验证与撤销的终极指南 🔐 【免费下载链接】bc-csharp BouncyCastle.NET Cryptography Library (Mirror) 项目地址: https://gitcode.com/gh_mirrors/bc/bc-csharp 在当今数字安全至关重要的时代ÿ…...
图像质量评估新视角:抛开PSNR和SSIM,聊聊如何用‘变异系数’量化局部细节清晰度
图像质量评估新视角:用变异系数量化局部细节清晰度的实战指南 在数字图像处理领域,评估图像质量一直是核心挑战。传统指标如PSNR(峰值信噪比)和SSIM(结构相似性)虽然广泛应用,但面对复杂场景时往…...
基于FET6254-C多核异构处理器的智能运动控制系统设计与实践
1. 项目概述:当运动控制遇上嵌入式智能最近在做一个智能运动控制的项目,从传统的PLC方案转向了更灵活、更智能的嵌入式平台。选型过程中,飞凌嵌入式的FET6254-C核心板进入了我的视野,经过一番深度评估和实际测试,它确实…...
Steam游戏清单一键下载:告别繁琐操作,3分钟搞定你的游戏库管理
Steam游戏清单一键下载:告别繁琐操作,3分钟搞定你的游戏库管理 【免费下载链接】Onekey Onekey Steam Depot Manifest Downloader 项目地址: https://gitcode.com/gh_mirrors/one/Onekey 还在为复杂的Steam游戏清单下载而烦恼吗?Oneke…...
监控与日志:Prometheus+Grafana实时追踪GPU、显存、推理延迟与错误率
系列导读 你现在看到的是《本地大模型私有化部署与优化:从入门到生产级实战》的第 8/10 篇,当前这篇会重点解决:让你的本地大模型服务像云服务一样可观测,提前发现并解决性能问题。 上一篇回顾:第 7 篇《量化部署终极指南:从GPTQ到AWQ,精度损失与显存节省的平衡艺术》…...
2026 免费GEO监测:AI搜索优化实用工具推荐
2026年AI搜索优化(GEO)已经成为企业数字营销的核心环节。当前GEO工具市场呈现明显的国内外分化格局,国内工具和海外工具在功能支持、适用场景上存在巨大差异。本文选取目前市场上主流的5款GEO工具,从功能完整性、AI模型支持、易用…...
3步掌握OmenSuperHub:惠普游戏本性能控制终极指南
3步掌握OmenSuperHub:惠普游戏本性能控制终极指南 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否厌倦了官方Omen Gaming Hub的臃肿界面…...
CanFestival实战:从心跳、TPDO/RPDO配置到回调函数的完整链路解析
1. CanFestival协议栈基础认知 第一次接触CanFestival时,我也被各种专业术语搞得晕头转向。简单来说,它就是个开源的CANopen协议栈实现,专门用于嵌入式设备间的通信。就像两个说同一种方言的人能顺畅交流一样,CanFestival让不同厂…...
使用Taotoken的Token Plan套餐实现更具成本优势的持续调用
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用Taotoken的Token Plan套餐实现更具成本优势的持续调用 对于有稳定大模型调用需求的开发者或团队而言,成本的可预测…...
Node.js服务端应用无缝集成Taotoken提供多模型AI能力
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Node.js服务端应用无缝集成Taotoken提供多模型AI能力 将大模型能力集成到Node.js后端服务中,可以快速为应用增加智能对…...
