https://www.eclipse.org/paho/downloads.php
eclipse/paho.mqtt.c库(使用v1.3.0)的下载地址是:https://github.com/eclipse/paho.mqtt.c/tree/v1.3.0
1、paho.mqtt.c-1.3.0\CMakeLists.txt,使能PAHO_BUILD_STATIC 和PAHO_BUILD_SAMPLES
## build options
SET(PAHO_WITH_SSL FALSE CACHE BOOL "Flag that defines whether to build ssl-enabled binaries too. ")
SET(PAHO_BUILD_STATIC TRUE CACHE BOOL "Build static library") #firecat modify
SET(PAHO_BUILD_DOCUMENTATION FALSE CACHE BOOL "Create and install the HTML based API documentation (requires Doxygen)")
SET(PAHO_BUILD_SAMPLES TRUE CACHE BOOL "Build sample programs") #firecat modify
SET(PAHO_BUILD_DEB_PACKAGE FALSE CACHE BOOL "Build debian package")
SET(PAHO_ENABLE_TESTING TRUE CACHE BOOL "Build tests and run")
SET(PAHO_ENABLE_CPACK TRUE CACHE BOOL "Enable CPack")
2、paho.mqtt.c-1.3.0\src\samples\CMakeLists.txt
#******************************************************************************* # Copyright (c) 2015, 2017 logi.cals GmbH and others # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # and Eclipse Distribution License v1.0 which accompany this distribution. # # The Eclipse Public License is available at # http://www.eclipse.org/legal/epl-v10.html # and the Eclipse Distribution License is available at # http://www.eclipse.org/org/documents/edl-v10.php. # # Contributors: # Rainer Poisel - initial version # Ian Craggs - update sample names #*******************************************************************************/ # Note: on OS X you should install XCode and the associated command-line tools ## compilation/linkage settings INCLUDE_DIRECTORIES( . ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR} ) IF (WIN32) ADD_DEFINITIONS(/DCMAKE_BUILD /D_CRT_SECURE_NO_DEPRECATE) ENDIF() # sample files c #ADD_EXECUTABLE(paho_c_pub paho_c_pub.c pubsub_opts.c) #firecat #ADD_EXECUTABLE(paho_c_sub paho_c_sub.c pubsub_opts.c) #ADD_EXECUTABLE(paho_cs_pub paho_cs_pub.c pubsub_opts.c) #ADD_EXECUTABLE(paho_cs_sub paho_cs_sub.c pubsub_opts.c) #TARGET_LINK_LIBRARIES(paho_c_pub paho-mqtt3as) #TARGET_LINK_LIBRARIES(paho_c_sub paho-mqtt3as) #TARGET_LINK_LIBRARIES(paho_cs_pub paho-mqtt3cs) #TARGET_LINK_LIBRARIES(paho_cs_sub paho-mqtt3cs) ADD_EXECUTABLE(MQTTAsync_subscribe MQTTAsync_subscribe.c) ADD_EXECUTABLE(MQTTAsync_publish MQTTAsync_publish.c) ADD_EXECUTABLE(MQTTClient_subscribe MQTTClient_subscribe.c) ADD_EXECUTABLE(MQTTClient_publish MQTTClient_publish.c) ADD_EXECUTABLE(MQTTClient_publish_async MQTTClient_publish_async.c) TARGET_LINK_LIBRARIES(MQTTAsync_subscribe paho-mqtt3a) TARGET_LINK_LIBRARIES(MQTTAsync_publish paho-mqtt3a) TARGET_LINK_LIBRARIES(MQTTClient_subscribe paho-mqtt3c) TARGET_LINK_LIBRARIES(MQTTClient_publish paho-mqtt3c) TARGET_LINK_LIBRARIES(MQTTClient_publish_async paho-mqtt3c) #INSTALL(TARGETS paho_c_sub #firecat # paho_c_pub # paho_cs_sub # paho_cs_pub # MQTTAsync_subscribe # MQTTAsync_publish # MQTTClient_subscribe # MQTTClient_publish # MQTTClient_publish_async # RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
3、使用cmake release编译,生成以下的动态库和静态库文件:
The Paho C client comprises four shared libraries:
libmqttv3a.so - asynchronous
libmqttv3as.so - asynchronous with SSL
libmqttv3c.so - "classic" / synchronous
libmqttv3cs.so - "classic" / synchronous with SSL
Optionally, using the CMake build, you can build static versions of those libraries.
libpaho-mqtt3a.so
libpaho-mqtt3a.so.1
libpaho-mqtt3a.so.1.3.0
libpaho-mqtt3a-static.a
libpaho-mqtt3c.so
libpaho-mqtt3c.so.1
libpaho-mqtt3c.so.1.3.0
libpaho-mqtt3c-static.a
把它们一起拷贝到路径:/usr/local/lib/
此时需要在/etc/ld.so.conf中加入库文件所在的目录:/usr/local/lib/
然后在终端执行命令,使之生效:
[root@localhost etc]# ldconfig
注意,/usr/local/lib/每次有库文件更新,都需要终端重新运行一次ldconfig这条命令。
4、使用案例
/******************************************************************************* * Copyright (c) 2012, 2017 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Ian Craggs - initial contribution *******************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "MQTTClient.h" #include <unistd.h> #include <errno.h> #include <signal.h> #include <sys/resource.h> /*setrlimit */ #include <fcntl.h> //daemonize #define ADDRESS "tcp://192.168.83.128:1883" #define CLIENTID "id001" #define TOPIC "keepalived" #define PAYLOAD "Hello World!" #define QOS 0 #define USERNAME "inTerm" #define PASSWORD "in2018" static int run = 1; volatile MQTTClient_deliveryToken deliveredtoken; void daemonize(void) { //come from /redis/server.c/daemonize() int fd; if (fork() != 0) exit(0); /* parent exits */ setsid(); /* create a new session */ /* Every output goes to /dev/null. If Redis is daemonized but * the 'logfile' is set to 'stdout' in the configuration file * it will not log at all. */ if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } } void signal_exit_func(int signo) { run = 0; printf("exit signo is %d\n", signo); } void signal_exit_handler() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_exit_func; sigaction(SIGINT, &sa, NULL);//当按下ctrl+c时,它的效果就是发送SIGINT信号 sigaction(SIGTERM, &sa, NULL);//kill pid sigaction(SIGQUIT, &sa, NULL);//ctrl+\代表退出SIGQUIT //SIGSTOP和SIGKILL信号是不可捕获的,所以下面两句话写了等于没有写 sigaction(SIGKILL, &sa, NULL);//kill -9 pid sigaction(SIGSTOP, &sa, NULL);//ctrl+z代表停止 //#define SIGTERM 15 //#define SIGKILL 9 //kill和kill -9,两个命令在linux中都有杀死进程的效果,然而两命令的执行过程却大有不同,在程序中如果用错了,可能会造成莫名其妙的现象。 //执行kill pid命令,系统会发送一个SIGTERM信号给对应的程序。 //执行kill -9 pid命令,系统给对应程序发送的信号是SIGKILL,即exit。exit信号不会被系统阻塞,所以kill -9能顺利杀掉进程。 } void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { int i; char* payloadptr; printf("Message arrived\n"); printf(" topic: %s\n", topicName); printf(" message: "); payloadptr = message->payload; for(i=0; i<message->payloadlen; i++) { putchar(*payloadptr++); } putchar('\n'); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } void connlost(void *context, char *cause)//心跳时间达到,如果没有收到服务器的reponse,客户端的socket会自动关闭 { printf("\nConnection lost\n"); printf(" cause: %s\n", cause); exit(EXIT_FAILURE); //firecat } //./MQTTClient_firecat "tcp://192.168.83.128:1883" "id001" int main(int argc, char* argv[]) { int background = 1;//firecat add if (background) { daemonize(); } //signal(SIGHUP, SIG_IGN); //开启的话,就捕获不到终端窗口关闭的信号了。即窗口关闭,进程仍然进行。 signal(SIGPIPE, SIG_IGN); char *serverURI; char *clientId; if (argc == 1) { serverURI = ADDRESS; clientId = CLIENTID; } else if (argc == 3) { serverURI = argv[1]; clientId = argv[2]; } else { printf("argc error\n"); exit(EXIT_FAILURE); } MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; int rc; int ch; MQTTClient_create(&client, serverURI, clientId, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 60; conn_opts.cleansession = 1; conn_opts.MQTTVersion = MQTTVERSION_3_1_1; conn_opts.username = USERNAME; conn_opts.password = PASSWORD; MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered); if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n" "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS); MQTTClient_subscribe(client, TOPIC, QOS); if (background) { while (run) { sleep(1); } } else { do { ch = getchar(); } while(ch!='Q' && ch != 'q'); } MQTTClient_unsubscribe(client, TOPIC); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; }