Qt工程使用MQTT-C库与mqtt服务器数据通信

实现mqtt订阅与发布话题,与mqtt服务器进行数据通信

编译环境:Qt5.15.2 + vs2019

需要mqttc库:mqttc.lib, mqttc.dll(根据MQTT-C源码编译出来的库,参考cmake编译MQTT-C源码-CSDN博客)

一、Qt pro文件编写

在Demo中创建mqtt-c文件夹,将mqttc库放在指定文件夹下,MQTT-C头文件包括mqtt_pal.h与mqtt.h。

QT += quickCONFIG += c++17SOURCES += \main.cppRESOURCES += qml.qrcINCLUDEPATH += $$PWD/ mqtt-c/include \$$PWD/mqtt-c/templates# 链接静态库
LIBS += -L$$PWD/mqtt-c/lib -lmqttcDebugBuild {DESTDIR  = $${OUT_PWD}/debug
} else {DESTDIR  = $${OUT_PWD}/release
}win32 {message("Building for MQTT-C Windows")# MQTT文件夹名MQTT_PATH = mqtt-cDESTDIR_WIN = $$replace(DESTDIR, "/", "\\")message($$DESTDIR_WIN)# 拷贝动态库MQTTC_DLL = \$$PWD\\$$MQTT_PATH\\bin\\mqttc.dll# 拷贝动态库到exe可执行文件同级文件夹下QMAKE_POST_LINK += $$escape_expand(\\n) $$QMAKE_COPY \"$$MQTTC_DLL\" \"$$DESTDIR_WIN\"
}# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
二、实现Mqtt发布、订阅话题功能,与mqtt服务器数据通信。 
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <iostream>#include "posix_sockets.h"
#include "mqtt.h"  // 包含MQTT库的头文件const char* DEFAULT_HOST = "47.120.xx.xxx"; // 替换成mqtt服务器地址
const char* DEFAULT_PORT = "1883";
const char* TOPIC = "testtopic/MAV";void publish_callback(void** unused, struct mqtt_response_publish *published) {// 收到发布消息时的回调char* topic_name = (char*)malloc(published->topic_name_size + 1);memcpy(topic_name, published->topic_name, published->topic_name_size);topic_name[published->topic_name_size] = '\0';// 修复收到的多余字符char* message = (char*)malloc(published->application_message_size + 1);memcpy(message, published->application_message, published->application_message_size);message[published->application_message_size] = '\0';  // 添加结束符std::cout << "Received message on topic: " << std::string((const char*)published->topic_name, published->topic_name_size)<< ", message: " << message << std::endl;
}DWORD WINAPI client_refresher(LPVOID client) {while (1) {mqtt_sync((struct mqtt_client*)client);Sleep(100);}return 0;
}int main(int argc, char *argv[]) {QGuiApplication app(argc, argv);QQmlApplicationEngine engine;WSADATA wsaData;if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {qDebug() << "WSAStartup failed.";return -1;}//SOCKET sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);int sockfd = open_nb_socket(DEFAULT_HOST, DEFAULT_PORT);if (sockfd == INVALID_SOCKET) {qDebug() << "Socket creation failed.";WSACleanup();return -1;}struct mqtt_client client;uint8_t sendbuf[2048];uint8_t recvbuf[1024];mqtt_init(&client, sockfd, sendbuf, sizeof(sendbuf), recvbuf, sizeof(recvbuf), publish_callback);/* Create an anonymous session */const char* client_id = NULL;/* Ensure we have a clean session */uint8_t connect_flags = MQTT_CONNECT_CLEAN_SESSION;/* Send connection request to the broker. */mqtt_connect(&client, client_id, NULL, NULL, 0, NULL, NULL, connect_flags, 400);/* check that we don't have any errors */if (client.error != MQTT_OK) {qDebug() << "error:" << mqtt_error_str(client.error);//fprintf(stderr, "error: %s\n", mqtt_error_str(client.error));}// 订阅mqtt_subscribe(&client, TOPIC, 0);HANDLE refresh_thread = CreateThread(NULL, 0, client_refresher, &client, 0, NULL);if (refresh_thread == NULL) {qDebug() << "Failed to start client daemon thread.";mqtt_disconnect(&client);closesocket(sockfd);WSACleanup();return -1;}// 发布const char* _mockData = "CusData";mqtt_publish(&client, TOPIC, _mockData, strlen(_mockData), MQTT_PUBLISH_QOS_0);engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty()) {qDebug() << "Failed to load QML.";return -1;}int result = app.exec();WaitForSingleObject(refresh_thread, INFINITE);CloseHandle(refresh_thread);mqtt_disconnect(&client);closesocket(sockfd);WSACleanup();return result;
}
三、编译报错

1、“close”: 找不到标识符报错
..\Qt-MQTT-C-Demo\mqtt-c\templates\posix_sockets.h(46): error C3861: “close”: 找不到标识符
原因是posix_sockets.h源码只适配了Linux,需要做Windows端的适配。

2、无法解析的外部符号 __imp_closesocket、无法解析的外部符号 __imp_socket 报错

原因:__imp_closesocket 等无法解析的外部符号,都是 Windows 网络 API(Winsock 库)中的函数。在 Windows 上,使用网络相关的功能时,通常需要链接 ws2_32.lib 库。

问题是由于在链接阶段没有包含 ws2_32.lib,这是 Winsock 库的静态链接库。

解决方案:确保项目正确地链接了 ws2_32.lib

在mcin.cpp使用到了 mqtt地方加上 #pragma comment(lib,"ws2_32.lib")

四、完整的MQTT发布与订阅Demo代码https://download.csdn.net/download/qq_38159549/89730327icon-default.png?t=O83Ahttps://download.csdn.net/download/qq_38159549/89730327

Demo基于MQTT-C examples下simple_publisher.c simple_subscriber.c例子修改。

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

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

相关文章

数据结构C //线性表ADT结构及相关函数

数据结构&#xff08;C语言版&#xff09;严蔚敏 吴伟民 线性表ADT结构及相关函数 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&#xff08;头文件&#xff0c;函数文件&#xff0c;主文件&#xff09; list.h头文件 /****…

LeetCode 2181.合并零之间的节点

题目描述 给你一个链表的头节点 head &#xff0c;该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val 0 。 对于每两个相邻的 0 &#xff0c;请你将它们之间的所有节点合并成一个节点&#xff0c;其值是所有已合并节点的值之和。然后将所有 0 …

浏览器百科:网页存储篇-如何在Chrome中打开IndexedDB窗格(十一)

1.引言 在现代Web开发中&#xff0c;网页存储技术扮演着至关重要的角色。IndexedDB作为一种低级API&#xff0c;允许客户端存储大量结构化数据&#xff0c;并提供高性能的搜索能力。在上一篇文章中&#xff0c;我们深入探讨了IndexedDB的基础知识及其应用场景。为了更有效地调…

C语言 - 断言

C语言 断言 用途 单片机编程中的断言主要有以下几个用途&#xff1a; 错误检测&#xff1a;通过检查程序运行时的状态&#xff0c;确保满足预期条件。如果条件不满足&#xff0c;则可以立即发现并处理潜在的错误。 参数验证&#xff1a;在函数或方法的开始处使用断言来验证输…

安全产品概述

防火墙 防火墙的核心功能是过滤掉有害的流量&#xff0c;在专用网络和公共网络之间建立保护屏障。防火墙过滤通常基于一系列规则&#xff0c;如 IP 地址、域名、协议、端口号、关键字等&#xff0c;对入站和出站的流量进行过滤。这些规则也称为访问控制列表&#xff08;ACCESS…

HarmonyOS云端开发(三)

文章目录 一、操作数据表增删改查二、注册登录1.验证码注册2.验证码登录 一、操作数据表增删改查 更多方法可查看官方文档 // mine.ets // 云服务sdk import cloud from hw-agconnect/cloud // 数据库文件 可看前几篇文章 import {userInfo} from ../bd/userInfo import …

网络编程day04(UDP、Linux IO 模型)

目录 【1】UDP 1》通信流程 2》函数接口 1> recvfrom 2> sendto 3》代码展示 1> 服务器代码 2> 客户端代码 【2】Linux IO 模型 场景假设一 1》阻塞式IO&#xff1a;最常见、效率低、不耗费CPU 2》 非阻塞 IO&#xff1a;轮询、耗费CPU&#xff0c;可以处…

哈希表和时间复杂度

哈希表 &#xff08;Hash Table&#xff09;&#xff0c;它通过哈希函数将键值映射到特定的数组索引&#xff0c;从而实现高效的查找、插入和删除操作。其核心思想是将数据直接存储到具有固定大小的数组中&#xff0c;通过哈希函数计算出每个数据的存储位置。 主要特性 哈…

Spring Boot属性注入的多种方式!

Spring Boot的一个问题&#xff0c;证明你是不是真正的 "会用" Spring boot ?Spring Boot的一个问题&#xff0c;直接暴露你是不是真正使用Spring Boothttps://mp.weixin.qq.com/s?__bizMzkzMTY0Mjc0Ng&mid2247484040&idx1&sn64ad15d95e44c874cc890973…

2024年CCPC网络赛A题题解 —— 军训Ⅰ(gym105336A)

个人认为很唐的一道题&#xff0c;考虑到不少人可能懒得写&#xff0c;我这里给大家发个代码叭&#xff0c;还有一点点题解&#xff08;因为真的不是很难&#xff09;。这是题面&#xff1a; 然后我来讲讲怎么做&#xff0c;不觉得会有多少人题目意思都理解不了叭&#xff1f;这…

码上进阶_刷题模块测试_用例设计

码上进阶_刷题模块测试_用例设计 系统概述&#xff1a; 码上进阶是为程序员专门打造的交流平台&#xff0c;采用主流的微服务框架和C端技术栈作为技术基础。在这个平台上&#xff0c;程序员 可以通过刷题、练习和模拟面试来提升自己的面试能力。 功能测试&#xff1a; 登录…

深度学习从入门到精通——感知损失介绍及基本实现

Perceptual Losses 感知损失&#xff08;Perceptual Loss&#xff09;感知损失的定义 图像转换问题&#xff08;Image Transformation Tasks&#xff09;现有方法代码解释感知损失&#xff08;Perceptual Loss&#xff09;1. 感知损失的背景2. 感知损失的定义3. 感知损失的优点…

Linux 常用命令 - tail 【显示文件最后几行内容】

简介 tail 这个命令源自英文单词 “尾巴”&#xff0c;它的主要功能是显示文件的最后几行内容。通过使用 tail&#xff0c;用户可以查看文件的最新添加内容&#xff0c;特别是对于监控日志文件来说非常有用。tail 命令默认显示文件的最后 10 行&#xff0c;但这可以通过参数调…

数学建模_数据预处理流程(全)

数据预处理整体流程图 一般数据预处理流程 处理缺失值&#xff1a;填补或删除缺失值。处理异常值&#xff1a;检测并处理异常值。数据编码&#xff1a;将分类变量进行标签编码或独热编码。数据标准化/归一化&#xff1a;对数据进行标准化或归一化处理。连续变量离散化&#xff…

基于JAVA+SpringBoot+Vue的企业级工位管理系统

基于JAVASpringBootVue的企业级工位管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; …

docker 启动ElasticSearch

拉取es镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.0运行 Elasticsearch 容器 docker run -d \--name elasticsearch \-p 9200:9200 \-p 9300:9300 \-e "discovery.typesingle-node" \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \# -…

WinCC 中对 VBS 进行单步执行调试

以前应该写过文章给各位展示如何在WinCC 中通过自身控件对脚本&#xff08;C、VBS&#xff09;进行脚本诊断和排错。但是也有用户反馈说在编写了一些相对复杂的脚本后&#xff0c;WinCC自身控件无法做到单步调试&#xff0c;也会影响脚本的诊断调试效率。如果能够对WinCC 中的脚…

论文解读:《LAMM: Label Alignment for Multi-Modal Prompt Learning》

系列文章目录 文章目录 系列文章目录LAMM: Label Alignment for Multi-Modal Prompt Learning学习1、论文细节理解1、研究背景2、论文贡献3、方法框架4、研究思路5、实验6、限制 LAMM: Label Alignment for Multi-Modal Prompt Learning学习 1、论文细节理解 VL模型和下游任务…

数学建模笔记—— 最大最小化规划模型

数学建模笔记—— 最大最小化规划模型 最大最小化规划模型1. 模型原理2. 典型例题3. matlab代码求解 最大最小化规划模型 1. 模型原理 在博弈论中有一个经典理论一一最大最小策略( Minimax strategy)&#xff0c;是由博弈论奠基人约翰冯诺伊曼(John von Neumann)在1928年提出…

LeetCode:2181. 合并零之间的节点 遍历链表

2181. 合并零之间的节点 today 2181. 合并零之间的节点 题目描述 给你一个链表的头节点 head &#xff0c;该链表包含由 0 分隔开的一连串整数。链表的开端和末尾的节点都满足Node.val 0 。 对于每两个相邻的0&#xff0c;请你将它们之间的所有节点合并成一个节点&#xf…