MFC连接mqtt服务器订阅和发送数据-自设计函数库

以下是一个简单的MQTT连接库文件,其中包含了连接、断开、订阅主题、发送数据和接收数据等函数。请注意,这只是一个示例,你可能需要根据自己的实际需求进行修改。

#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>const std::string SERVER_ADDRESS = "mqtt.server.com";
const int SERVER_PORT = 1883;// MQTT固定报头结构
struct MqttFixedHeader {uint8_t controlPacketType;uint8_t remainingLength;
};// MQTT连接报文结构
struct MqttConnectPacket {MqttFixedHeader fixedHeader;uint8_t variableHeader[10];uint8_t payload[20];
};// MQTT订阅报文结构
struct MqttSubscribePacket {MqttFixedHeader fixedHeader;uint16_t packetIdentifier;uint8_t topic[20];uint8_t qos;
};// MQTT发布报文结构
struct MqttPublishPacket {MqttFixedHeader fixedHeader;uint16_t topicLength;uint8_t topic[20];uint8_t payload[100];
};class MqttClient {
public:MqttClient() : sockfd(-1), connected(false) {}~MqttClient() {if (connected) {disconnect();}}bool connect(const std::string& clientId) {sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {std::cerr << "Failed to create socket" << std::endl;return false;}struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SERVER_PORT);if (inet_pton(AF_INET, SERVER_ADDRESS.c_str(), &(serv_addr.sin_addr)) <= 0) {std::cerr << "Failed to set server address" << std::endl;return false;}if (connect(sockfd, reinterpret_cast<struct sockaddr*>(&serv_addr), sizeof(serv_addr)) < 0) {std::cerr << "Connection failed" << std::endl;return false;}// 构建MQTT连接报文MqttConnectPacket connectPacket;connectPacket.fixedHeader.controlPacketType = 0x10; // 连接请求connectPacket.fixedHeader.remainingLength = 0x0C; // 可变报头长度为12字节memcpy(connectPacket.variableHeader, "MQTT", 4);connectPacket.variableHeader[4] = 0x04; // MQTT协议版本号(4)connectPacket.variableHeader[5] = 0x02; // 连接标志connectPacket.variableHeader[6] = 0x00; // 保持连接时间的最高8位connectPacket.variableHeader[7] = 0x3C; // 保持连接时间的最低8位connectPacket.variableHeader[8] = 0x00; // 清理会话位为0connectPacket.variableHeader[9] = 0x00; // 预留位为0memcpy(connectPacket.payload, clientId.c_str(), clientId.length());// 发送MQTT连接报文if (send(sockfd, &connectPacket, sizeof(connectPacket), 0) < 0) {std::cerr << "Failed to send connect packet" << std::endl;return false;}// 接收MQTT服务器的响应uint8_t response[1024];ssize_t bytesRead = recv(sockfd, response, sizeof(response), 0);if (bytesRead <= 0) {std::cerr << "Failed to receive response" << std::endl;return false;}// 处理MQTT服务器的响应connected = true;return true;}void disconnect() {if (connected) {close(sockfd);sockfd = -1;connected = false;}}bool subscribe(const std::string& topic, uint8_t qos) {if (!connected) {std::cerr << "Not connected" << std::endl;return false;}// 构建MQTT订阅报文MqttSubscribePacket subscribePacket;subscribePacket.fixedHeader.controlPacketType = 0x82; // 订阅请求subscribePacket.fixedHeader.remainingLength = 0x0E; // 可变报头长度为14字节subscribePacket.packetIdentifier = 0x1234; // 包标识符memcpy(subscribePacket.topic, topic.c_str(), topic.length());subscribePacket.qos = qos; // QoS等级// 发送MQTT订阅报文if (send(sockfd, &subscribePacket, sizeof(subscribePacket), 0) < 0) {std::cerr << "Failed to send subscribe packet" << std::endl;return false;}// 接收MQTT服务器的响应uint8_t response[1024];ssize_t bytesRead = recv(sockfd, response, sizeof(response), 0);if (bytesRead <= 0) {std::cerr << "Failed to receive response" << std::endl;return false;}// 处理MQTT服务器的响应return true;}bool publish(const std::string& topic, const std::string& message, uint8_t qos) {if (!connected) {std::cerr << "Not connected" << std::endl;return false;}// 构建MQTT发布报文MqttPublishPacket publishPacket;publishPacket.fixedHeader.controlPacketType = 0x30; // 发布消息publishPacket.fixedHeader.remainingLength = 0x2D; // 可变报头长度为45字节publishPacket.topicLength = topic.length();memcpy(publishPacket.topic, topic.c_str(), topic.length());memcpy(publishPacket.payload, message.c_str(), message.length());// 发送MQTT发布报文if (send(sockfd, &publishPacket, sizeof(publishPacket), 0) < 0) {std::cerr << "Failed to send publish packet" << std::endl;return false;}// 处理MQTT服务器的响应return true;}ssize_t receive(uint8_t* buffer, size_t bufferSize) {if (!connected) {std::cerr << "Not connected" << std::endl;return -1;}return recv(sockfd, buffer, bufferSize, 0);}private:int sockfd;bool connected;
};

在上述代码中,我们将MQTT连接功能封装到了一个名为MqttClient的类中,并提供了连接、断开、订阅主题、发送数据和接收数据等函数。你可以根据自己的实际需求调用这些函数。

例如,要连接到MQTT服务器,请使用以下代码:

MqttClient client;
if (client.connect("client_id")) {// 连接成功
} else {// 连接失败
}

要订阅主题,请使用以下代码:

if (client.subscribe("topic", 0x01)) {// 订阅成功
} else {// 订阅失败
}

要发布消息,请使用以下代码:

if (client.publish("topic", "message", 0x01)) {// 发布成功
} else {// 发布失败
}

要接收消息,请使用以下代码:

uint8_t buffer[1024];
ssize_t bytesRead = client.receive(buffer, sizeof(buffer));
if (bytesRead >= 0) {// 处理接收到的数据
} else {// 接收数据失败
}

下面是一个完整的MQTT连接示例,包括从用户输入地址和端口到订阅主题和发送消息的全部过程:

#include <iostream>
#include <string>// 导入上述的MQTT连接库文件int main() {std::string serverAddress;int serverPort;std::string clientId;std::string topic;// 获取用户输入的MQTT服务器地址和端口std::cout << "Enter MQTT server address: ";std::cin >> serverAddress;std::cout << "Enter MQTT server port: ";std::cin >> serverPort;std::cout << "Enter client ID: ";std::cin >> clientId;MqttClient client;// 连接到MQTT服务器if (client.connect(clientId)) {std::cout << "Connected to MQTT server" << std::endl;// 订阅主题std::cout << "Enter topic to subscribe: ";std::cin >> topic;if (client.subscribe(topic, 0x01)) {std::cout << "Subscribed to topic: " << topic << std::endl;} else {std::cerr << "Failed to subscribe to topic" << std::endl;return -1;}// 发布消息std::string message;std::cout << "Enter message to publish: ";std::cin.ignore(); // 忽略之前的换行符std::getline(std::cin, message);if (client.publish(topic, message, 0x01)) {std::cout << "Published message: " << message << std::endl;} else {std::cerr << "Failed to publish message" << std::endl;return -1;}// 接收消息uint8_t buffer[1024];ssize_t bytesRead = client.receive(buffer, sizeof(buffer));if (bytesRead >= 0) {std::string receivedMessage(reinterpret_cast<char*>(buffer), bytesRead);std::cout << "Received message: " << receivedMessage << std::endl;} else {std::cerr << "Failed to receive message" << std::endl;return -1;}client.disconnect();std::cout << "Disconnected from MQTT server" << std::endl;} else {std::cerr << "Failed to connect to MQTT server" << std::endl;return -1;}return 0;
}

在这个示例中,我们使用std::cin从用户那里获取了MQTT服务器的地址、端口、客户端ID以及要订阅和发布的主题和消息。然后,我们通过调用相应的函数来进行连接、订阅、发布和接收。

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

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

相关文章

分布式技术之故障隔离技术

文章目录 什么是故障隔离&#xff1f;分布式故障隔离策略线程级隔离进程级隔离资源隔离故障隔离策略综合对比 什么是故障隔离&#xff1f; 故障隔离就是&#xff0c;把故障通过某种方式与其他正常模块进行隔离&#xff0c;以保证某一模块出现故障后&#xff0c;不会影响其他模…

NuScenes Dataset的坐标系及OpenPCDet里针对NuScenes Dataset格式的输入输出数据的坐标系转换

网上很多文章只提了NuScenes坐标系有哪些&#xff0c;但是没有找到一篇文章把NuScenes坐标系的转换结合代码说全说明白了&#xff0c;结合工作需要&#xff0c;针对OpenPCDet里读取NuScenes数据集对数据做坐标转换的代码说一下。 OpenPCDet是3D点云目标检测框架&#xff0c;顾…

20231229在Firefly的AIO-3399J开发板的Android11使用挖掘机的DTS配置单前后摄像头ov13850

20231229在Firefly的AIO-3399J开发板的Android11使用挖掘机的DTS配置单前后摄像头ov13850 2023/12/29 11:10 开发板&#xff1a;Firefly的AIO-3399J【RK3399】 SDK&#xff1a;rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.…

机器学习:走向智能化未来的钥匙

机器学习是人工智能领域中的一项关键技术&#xff0c;它使计算机系统能够从经验中学习&#xff0c;并通过数据驱动的方式不断优化和改进性能。本文将深入介绍机器学习的基本原理、发展历程、主要算法、应用领域以及未来趋势&#xff0c;带领读者深入了解这门推动科技创新的引擎…

2023年03月21日_chatgpt宕机事件的简单回顾

你能想象吗 ChatGPT挂了 昨天半夜呢 来自全球各地的用户纷纷发现 ChatGPT的网站弹出了报错警告的信息 然后立即就无法使用了 即使是有特权的plus账户也未能幸免 一时之间呢 chatgptdown的话题在Twitter刷屏 不少重度的用户表示很着急 有的用户说呢没了ChatGPT 这工作…

MySQL入门教程-函数,索引

4MySQL函数 常用函数 -- 数学运算SELECT ABS(-8); -- 绝对值SELECT CEIL(5.1); -- 向上取整SELECT CEILING(5.1); -- 向上取整SELECT RAND(); -- 返回0~1之间的一个随机数SELECT SIGN(-10); -- 返回一个数的符号;0返回0;正数返回1;负数返回-1​-- 字符串函数SELECT CHAR_LENGT…

推荐系统中的 业务指标 覆盖率

覆盖率&#xff08;Coverage&#xff09;是推荐系统评估指标之一&#xff0c;用于衡量推荐系统是否能够覆盖物品空间中的多样性&#xff0c;即是否能够推荐系统中的每个物品都能够被推荐给用户。覆盖率通常是一个百分比&#xff0c;表示被推荐的物品占总物品集合的比例。 覆盖…

设计模式-调停者模式

设计模式专栏 模式介绍模式特点应用场景调停者模式与命令模式的比较代码示例Java实现调停者模式Python实现调停者模式 调停者模式在spring中的应用 模式介绍 调停者模式是一种软件设计模式&#xff0c;主要用于模块间的解耦&#xff0c;通过避免对象之间显式的互相指向&#x…

使用软件解决T490笔记本57摄氏度温度墙的问题

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 客户使用LenovoT490跑GQRX SDR&#xff0c;接入SDR在5MHz采样率下&#xff0c;机器卡顿。这对于10代i7CPU显然是不正常的。后续发现上网页也卡&#xff0c;卸载杀毒、重装系统、BIOS电源设置、系统最…

#if #ifdef和#ifndef的综合应用。

#include<stdio.h> #define MAX #define MAXIMUM(x,y)(x>y)?x:y #define MINIMUM(x,y) (x>y)?y:x int main() { int a10,b20; #ifdef MAX printf("更大的数字是 %d\n",MAXIMUM(a,b)); #else printf("更小的数字是 %d\n",MINIMUM…

24、Web攻防-通用漏洞SQL注入MYSQL跨库ACCESS偏移

文章目录 一、SQL注入原理   脚本代码在与数据库进行数据通讯时&#xff08;从数据库取出相关数据进行页面显示&#xff09;&#xff0c;使用预定义的SQL查询语句进行数据查询。能通过参数传递自定义值来实现SQL语句的控制&#xff0c;执行恶意的查询操作&#xff0c;例如查询…

【BERT】深入BERT模型2——模型中的重点内容,两个任务

前言 BERT出自论文&#xff1a;《BERT&#xff1a;Pre-training of Deep Bidirectional Transformers for Language Understanding》 2019年 近年来&#xff0c;在自然语言处理领域&#xff0c;BERT模型受到了极为广泛的关注&#xff0c;很多模型中都用到了BERT-base或者是BE…

nginx介绍、配置和使用

nginx介绍、配置和使用 1、nginx介绍2、nginx安装、配置3、nginx使用 1、nginx介绍 Nginx&#xff08;发音为"engine-x"&#xff09;是一个开源的高性能、高可靠性的HTTP服务器和反向代理服务器&#xff0c;也可以用作邮件代理服务器。它最初由Igor Sysoev于2004年创…

vscode文章汇总

Visual Studio Code (VSCode)&#xff0c;快速跳转到指定行的代码 vscode 搜索界面的files to include files to exclude 是什么功能&#xff1f; vscode 添加 ros头文件 VS Code的tasks.json配置文件如何编写? VS Code的launch.json配置文件如何编写? c_cpp_properties.js…

拓展操作(二) nginx 反向代理mysql 和redis操作

让清单成为一种习惯 互联网时代的变革,不再是简单的开发部署上线,持续,正确,安全地把事情做好尤其重要;把事情做好的前提是做一个可量化可执行的清单,让工程师就可以操作的清单而不是专家才能操作: 设定检查点 根据节点执行检查程序操作确认或边读边做 二者选其一不要太…

C++ 类打包LIB方法,创建 C 接口函数方法

起因&#xff1a;建立lib文件时&#xff0c;尽量提供最简单的接口参数及函数。不暴露内部数据结构&#xff01; 解&#xff1a; lib 源文件 Test.h #ifndef __TEST_H__ #define __TEST_H__#ifndef BOOL typedef unsigned char BOOL; #endifclass CTray { public: Ge…

Stable Diffusion WebUI制作光影文字效果

在huggingface上下载control_v1p_sd15_brightness模型。 将模型放在stable-diffusion-webui\extensions\sd-webui-controlnet\models目录下。 SD参数配置 正向提示词&#xff1a; city,Building,tall building,Neon Light, gentle light shines through, anime style, paint…

美团后端Java实习一面面经

说一下AOP&#xff1f; 面向切面编程&#xff0c;通过预编译方式和运行期动态代理实现程序功能的统一维护的技术。可以减少程序中相同代码的编写&#xff0c;简化开发&#xff0c;使得接口更加专注于业务 相关概念 Aspect&#xff08;切面&#xff09;&#xff1a; Aspect 声…

Python中property特性属性是什么

在Java中&#xff0c;通常在类中定义的成员变量为私有变量&#xff0c;在类的实例中不能直接通过对象.属性直接操作&#xff0c;而是要通过getter和setter来操作私有变量。 而在Python中&#xff0c;因为有property这个概念&#xff0c;所以不需要写getter和setter一堆重复的代…

当你遇到这些情况的时候,发版到白了少年头,代码还是不会更新...

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 一、问题描述&#xff1a; 之前遇到过几次这种情况&#xff1a;研发将代码提交之后&#xff0c;通过打包部署&#xff0c;发现部…