【全方位教程】使用 Paho MQTT C++ 库 + OpenSSL 实现安全 MQTT 客户端 — 从三方库编译到 CMake 构建及测试 Demo_c++ mqtt库
文章目录
- 【全方位教程】使用 Paho MQTT C++ 库 + OpenSSL 实现安全 MQTT 客户端 — 从三方库编译到 CMake 构建及测试 Demo
- 本文未经允许不得转发!!!
-
- 前言
- 一、目录结构设计及源码准备
-
- 准备源码
- 二、编写三方库独立构建脚本
-
- 2.1 OpenSSL `build.sh`
- 2.2 paho.mqtt.c `build.sh`
- 2.3 paho.mqtt.cpp `build.sh`
- 三、顶层 CMakeLists.txt 详解
- 四、MQTT 测试客户端代码示例
- 五、完整构建与运行步骤
- 六、常见问题及调试建议
- 七、后续扩展建议
- 总结
【全方位教程】使用 Paho MQTT C++ 库 + OpenSSL 实现安全 MQTT 客户端 — 从三方库编译到 CMake 构建及测试 Demo
本文未经允许不得转发!!!
前言
MQTT 是物联网中极为常用的轻量级消息协议。Eclipse 的 Paho 项目提供了功能丰富的 MQTT C 和 C++ 客户端库,支持同步和异步模式,且支持 SSL/TLS 加密。本文将手把手教你:
- 如何下载并编译 OpenSSL 和 Paho MQTT C / C++ 三方库
- 使用 CMake 编写模块化构建脚本
- 编写并运行一个简单的 MQTT 客户端 Demo,基于异步模式,且支持 SSL
- 目录结构设计及编译脚本编写经验分享
无论你是刚接触 MQTT,还是想搭建稳定安全的 MQTT 客户端,这篇教程都能帮助你快速上手。
MQTT Broker搭建可以参考https://blog.csdn.net/weixin_67293003/article/details/148381608?spm=1011.2124.3001.6209
基于该文章重新修改其配置mosquitto/mqtt/config/mosquitto.conf
# 配置端口号及远程访问IPlistener 1883 0.0.0.0# 数据存储路径persistence_location /mosquitto/data/# 运行日志存储路劲log_dest file /mosquitto/log/mosquitto.log# 设置匿名访问allow_anonymous trueroot
Ubuntu C++ 环境搭建参考此文章https://blog.csdn.net/weixin_67293003/article/details/148366300?spm=1011.2415.3001.5331
一、目录结构设计及源码准备
合理的目录结构是项目维护的基石。我们设计了如下结构:
proj/├── 3th_lib/# 第三方库目录│ ├── bin/# 编译安装后的头文件和库文件│ ├── src/# 第三方库源码│ │ ├── openssl/ # OpenSSL 源码及构建脚本│ │ │ └── build.sh│ │ ├── paho.mqtt.c/ # Paho MQTT C 库源码及构建脚本│ │ │ └── build.sh│ │ └── paho.mqtt.cpp/ # Paho MQTT C++ 库源码及构建脚本│ │ └── build.sh├── test/ # 测试 Demo│ └── test_mqtt_client.cpp└── CMakeLists.txt # 顶层 CMake 配置文件
准备源码
我们需要从官方仓库克隆最新或指定版本源码:
mkdir -p proj/3th_lib/srccd proj/3th_lib/src# OpenSSL源码下载(可选直接下载tar.gz)mkdir openssl && cd opensslwget https://www.openssl.org/source/openssl-3.0.16.tar.gztar -xf openssl-3.0.16.tar.gzmv openssl-3.0.16/ openssl# Paho MQTT Ccd ..git clone https://github.com/eclipse/paho.mqtt.c.gitcd paho.mqtt.cgit checkout v1.3.13# Paho MQTT C++cd ..git clone https://github.com/eclipse/paho.mqtt.cpp.gitcd paho.mqtt.cppgit checkout v1.2.0
二、编写三方库独立构建脚本
为了避免繁琐的重复步骤,同时方便维护和迁移,我们为每个三方库编写独立的 build.sh
,放在对应源码目录。
2.1 OpenSSL build.sh
#!/bin/bash# filepath: /root/proj/3th_lib/src/openssl/build.shset -eINSTALL_DIR=\"/root/proj/3th_lib/bin\"# 进入源码目录cd \"$(dirname \"$0\")\"apt-get updateapt-get install -y perl# 配置./Configure --prefix=\"$INSTALL_DIR\" linux-x86_64# 编译make -j$(nproc)# 安装make install_swecho \"OpenSSL 3.0.16 已安装到 $INSTALL_DIR\"
说明:
- 安装目录集中放在
3th_lib/bin
下,方便统一管理。
2.2 paho.mqtt.c build.sh
#!/bin/bash# filepath: /root/proj/3th_lib/src/paho.mqtt.c/build.shset -eINSTALL_DIR=\"/root/proj/3th_lib/bin\"OPENSSL_ROOT=\"/root/proj/3th_lib/bin\"# 安装依赖apt-get updateapt-get install -y cmake build-essential# 进入源码目录cd \"$(dirname \"$0\")\"# 清理旧构建rm -rf buildmkdir buildcd build# 配置编译参数,指定 OpenSSL 路径cmake .. \\ -DPAHO_WITH_SSL=ON \\ -DOPENSSL_ROOT_DIR=\"$OPENSSL_ROOT\" \\ -DOPENSSL_LIBRARIES=\"$OPENSSL_ROOT/lib\" \\ -DOPENSSL_INCLUDE_DIR=\"$OPENSSL_ROOT/include\" \\ -DCMAKE_INSTALL_PREFIX=\"$INSTALL_DIR\"# 编译并安装make -j$(nproc)make installecho \"paho.mqtt.c 已安装到 $INSTALL_DIR,使用 OpenSSL 路径 $OPENSSL_ROOT\"
说明:
- 使用
PAHO_WITH_SSL=ON
开启 SSL 支持。 - 明确
OPENSSL_ROOT_DIR
,让 CMake 找到刚才编译好的 OpenSSL。
2.3 paho.mqtt.cpp build.sh
#!/bin/bash# filepath: /root/proj/3th_lib/src/paho.mqtt.cpp/build.shset -eINSTALL_DIR=\"/root/proj/3th_lib/bin\"PAHO_C_DIR=\"/root/proj/3th_lib/bin\"OPENSSL_ROOT=\"/root/proj/3th_lib/bin\"# 安装依赖apt-get updateapt-get install -y cmake build-essential# 进入源码目录cd \"$(dirname \"$0\")\"# 清理旧构建rm -rf buildmkdir buildcd build# 配置编译参数,指定 paho.mqtt.c 和 OpenSSL 路径cmake .. \\ -DPAHO_WITH_SSL=ON \\ -DPAHO_MQTT_C_PATH=\"$PAHO_C_DIR\" \\ -DOPENSSL_ROOT_DIR=\"$OPENSSL_ROOT\" \\ -DOPENSSL_LIBRARIES=\"$OPENSSL_ROOT/lib\" \\ -DOPENSSL_INCLUDE_DIR=\"$OPENSSL_ROOT/include\" \\ -DCMAKE_INSTALL_PREFIX=\"$INSTALL_DIR\"# 编译并安装make -j$(nproc)make installecho \"paho.mqtt.cpp 已安装到 $INSTALL_DIR,依赖 paho.mqtt.c 和 OpenSSL 路径 $PAHO_C_DIR\"
说明:
PAHO_MQTT_C_PATH
告诉 C++ 库在哪里找到依赖的 C 库。- 关闭静态库构建,方便生成共享库。
三、顶层 CMakeLists.txt 详解
cmake_minimum_required(VERSION 3.10)project(SmartHome)# === 编译标准 ===set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)# === 开启编译器警告(建议开发时打开)===set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter\")# === 第三方库根目录 ===set(THIRD_PARTY_LIB_PREFIX /root/proj/3th_lib/bin)# === 头文件路径 ===include_directories( ${THIRD_PARTY_LIB_PREFIX}/include)# === 库文件路径 ===link_directories( ${THIRD_PARTY_LIB_PREFIX}/lib ${THIRD_PARTY_LIB_PREFIX}/lib64)message(STATUS \"Include directories: ${THIRD_PARTY_LIB_PREFIX}/include\")message(STATUS \"Library directories: ${THIRD_PARTY_LIB_PREFIX}/lib\")message(STATUS \"Library directories: ${THIRD_PARTY_LIB_PREFIX}/lib64\")# === 构建 & 安装时 RPATH 设置(确保运行时找到 .so 文件)===set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)set(CMAKE_INSTALL_RPATH \"${THIRD_PARTY_LIB_PREFIX}/lib;${THIRD_PARTY_LIB_PREFIX}/lib64\")set(CMAKE_BUILD_RPATH \"${THIRD_PARTY_LIB_PREFIX}/lib;${THIRD_PARTY_LIB_PREFIX}/lib64\")set(CMAKE_SKIP_BUILD_RPATH FALSE)# === 可执行文件 ===add_executable(test_mqtt_client ./test/test_mqtt_client.cpp)# === 链接依赖库 ===target_link_libraries(test_mqtt_client ssl crypto paho-mqttpp3 paho-mqtt3c)
四、MQTT 测试客户端代码示例
放在 test/test_mqtt_client.cpp
:
#include #include #include #include #include \"mqtt/async_client.h\"const std::string SERVER_ADDRESS = \"mqtt://10.7.0.4:1883\"; //填入自己的mqtt地址const std::string CLIENT_ID = \"paho_cpp_client\";const std::string TOPIC = \"test/topic\";const int QOS = 1;const auto TIMEOUT = std::chrono::seconds(10);class callback : public virtual mqtt::callback {public: void connected(const std::string& cause) override { std::cout << \"Connected: \" << cause << std::endl; } void connection_lost(const std::string& cause) override { std::cout << \"Connection lost: \" << cause << std::endl; } void message_arrived(mqtt::const_message_ptr msg) override { std::cout << \"Message arrived:\\n\" << \" topic: \" << msg->get_topic() << \"\\n\" << \" payload: \" << msg->to_string() << \"\\n\"; }};int main() { mqtt::async_client client(SERVER_ADDRESS, CLIENT_ID); callback cb; client.set_callback(cb); mqtt::connect_options connOpts; connOpts.set_clean_session(true); try { std::cout << \"Connecting to the MQTT server...\" << std::endl; client.connect(connOpts)->wait(); std::cout << \"Connected.\" << std::endl; std::cout << \"Subscribing to topic: \" << TOPIC << std::endl; client.subscribe(TOPIC, QOS)->wait(); std::this_thread::sleep_for(std::chrono::seconds(1)); std::string payload = \"Hello from Paho C++!\"; auto msg = mqtt::make_message(TOPIC, payload); msg->set_qos(QOS); std::cout << \"Publishing message...\" << std::endl; client.publish(msg)->wait(); // 等待消息到达 std::this_thread::sleep_for(std::chrono::seconds(5)); std::cout << \"Disconnecting...\" << std::endl; client.disconnect()->wait(); std::cout << \"Disconnected.\" << std::endl; } catch (const mqtt::exception& exc) { std::cerr << \"Error: \" << exc.what() << std::endl; return 1; } return 0;}
五、完整构建与运行步骤
- 编译 OpenSSL:
cd proj/3th_lib/src/opensslchmod +x build.sh./build.sh
- 编译 Paho MQTT C:
cd ../paho.mqtt.cchmod +x build.sh./build.sh
- 编译 Paho MQTT C++:
cd ../paho.mqtt.cppchmod +x build.sh./build.sh
- 构建并运行 Demo:
cd ../../../mkdir -p build && cd buildcmake ..make -j./test_mqtt_client
5.输出结果
root@xxx:~/proj/build# ./test_mqtt_client Connecting to the MQTT server...Connected: connect onSuccess calledConnected.Subscribing to topic: test/topicPublishing message...Message arrived: topic: test/topic payload: Hello from Paho C++!Disconnecting...Disconnected.
六、常见问题及调试建议
- 找不到 OpenSSL:确认
OPENSSL_ROOT_DIR
设置正确,build.sh
中路径要指向安装目录。 - MQTT SSL 连接失败:确认 Broker 地址及端口正确,且本地环境支持 SSL。可尝试不开启 SSL 连接确认功能正常。
- 权限问题:确保
build.sh
有执行权限,且 CMake 有正确执行环境。 - 库链接失败:确认
3th_lib/bin/lib
中有对应.so
或.a
文件,且LD_LIBRARY_PATH
包含此路径或通过 rpath 指定。 - test_mqtt_client 链接不到相关库,导入环境变量
export LD_LIBRARY_PATH=/root/proj/3th_lib/bin/lib:/root/proj/3th_lib/bin/lib64:$LD_LIBRARY_PATH
七、后续扩展建议
- 证书双向验证:使用客户端证书和密钥,增强安全性。
- 断线重连机制:结合定时器与连接状态检测实现自动重连。
- 跨平台支持:适配 Windows、macOS 等多平台环境。
- 更多示例:结合 QoS、遗嘱消息、持久会话等高级特性。
总结
本文介绍了如何从零开始编译并集成 OpenSSL、Paho MQTT C 和 C++ 库,构建一个支持 SSL 的异步 MQTT 客户端 Demo。
通过合理的目录结构和模块化构建脚本,项目结构清晰且易于维护。
希望这篇教程能助你顺利搭建安全稳定的 MQTT 客户端程序。
欢迎点赞、收藏和分享,也欢迎留言讨论你在 MQTT 应用中的问题与心得!