树莓派用Paho MQTT客户端SSL连接test.mosquitto.org返回-1报错求助
Paho MQTT SSL连接test.mosquitto.org返回-1问题解决方案
返回码-1对应MQTTCLIENT_FAILURE,绝大多数情况由SSL配置错误、证书无效或网络不通导致,以下是具体修复方案:
核心错误原因
- SSL参数配置错误:
CApath参数用于指定CA证书存放目录,单文件CA根证书需要赋值给trustStore参数,现有代码把mosquitto根证书路径错误赋值给了CApath - 客户端证书参数映射错误:
keyStore对应客户端证书(.crt文件),privateKey对应客户端私钥(.key文件),现有代码直接把私钥路径赋值给了keyStore,缺少客户端证书配置 - 缺少全局初始化调用:声明了
MQTTClient_global_init函数但没有执行,部分版本的Paho C客户端需要先初始化全局SSL资源才能正常建立连接 - 端口匹配问题:test.mosquitto.org的8884端口要求客户端提供有效证书,使用的client.crt、client.key必须是从test.mosquitto.org官方申请生成的对应证书,不能使用自定义生成的证书
排查步骤
- 先验证网络与证书有效性,在树莓派终端执行以下命令:
openssl s_client -connect test.mosquitto.org:8884 -CAfile ./mosquitto.org.crt -cert ./client.crt -key ./client.key
如果能正常完成SSL握手,说明网络和证书本身没有问题,否则先解决证书或网络连通性问题
2. 确认证书文件权限:客户端私钥文件权限必须设为600,否则SSL库会拒绝加载
chmod 600 client.key
- 确认程序运行时的工作目录下确实存在mosquitto.org.crt、client.crt、client.key三个文件
修正后的核心代码片段
#include <MQTTClient.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define ADDRESS "ssl://test.mosquitto.org:8884" #define CLIENTID "c1" #define TOPIC "ack" #define PAYLOAD "Hello World" #define QOS 1 #define TIMEOUT 10000L int main() { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc; // 新增全局初始化逻辑 MQTTClient_init_options init_opt = MQTTClient_init_options_initializer; MQTTClient_global_init(&init_opt); MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_DEFAULT, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; // 修正SSL参数配置 conn_opts.ssl = &ssl_opts; conn_opts.ssl->trustStore = "mosquitto.org.crt"; conn_opts.ssl->keyStore = "client.crt"; conn_opts.ssl->privateKey = "client.key"; conn_opts.ssl->enableServerCertAuth = 1; conn_opts.serverURIcount = 0; conn_opts.serverURIs = NULL; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } pubmsg.payload = PAYLOAD; pubmsg.payloadlen = (int)strlen(PAYLOAD); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); printf("Waiting for up to %d seconds for publication of %s\n" "on topic %s for client with ClientID: %s\n", (int)(TIMEOUT / 1000), PAYLOAD, TOPIC, CLIENTID); rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); printf("Message with delivery token %d delivered\n", token); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return 0; }
如果不需要客户端证书认证,可以将端口改为8883,移除keyStore和privateKey的配置即可。
内容的提问来源于stack exchange,提问作者xyz
相关产品推荐
相关产品推荐

