精华内容
下载资源
问答
  • 2021-08-23 14:27:03

    examples/sucribe/basic-1.c

    分析:

    1.  定义结构体   struct mosquitto   

    struct mosquitto {
    #if defined(WITH_BROKER) && defined(WITH_EPOLL)
        /* This *must* be the first element in the struct. */
        int ident;
    #endif

        ...
        mosq_sock_t sock;
        char *address;    // 指针变量 属性
        char *id;
        char *username;

        ...
        void (*on_connect)(struct mosquitto *, void *userdata, int rc);  //回调函数
        ...
    };
    结构体包含需要用到的变量属性和回调函数。对于不确定的长度的数据 如name定位为char *

    2.  应用

    int main(int argc, char *argv[])
    {
        struct mosquitto *mosq;      //定义指针变量
        int rc;
        mosquitto_lib_init();     
        mosq = mosquitto_new(NULL, true, NULL);   //实际为 mosq 分配一段内存
        if(mosq == NULL){
            fprintf(stderr, "Error: Out of memory.\n");
            return 1;
        }
        rc = mosquitto_connect(mosq, "test.mosquitto.org", 1883, 60);   
        if(rc != MOSQ_ERR_SUCCESS){
            mosquitto_destroy(mosq);  // 释放内存,重置部分指针变量和回调。
            fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
            return 1;
        }
        mosquitto_loop_forever(mosq, -1, 1);

        mosquitto_lib_cleanup();
        return 0;
    }

    特别说明

    struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata)
    {
        struct mosquitto *mosq = NULL;
        int rc;

        mosq = (struct mosquitto *)mosquitto__calloc(1, sizeof(struct mosquitto));  //分配内存
        if(mosq){
            mosq->sock = INVALID_SOCKET;

            mosq->sockpairR = INVALID_SOCKET;
            mosq->sockpairW = INVALID_SOCKET;
            rc = mosquitto_reinitialise(mosq, id, clean_start, userdata);  //这个函数分析如下
            if(rc){
                mosquitto_destroy(mosq);

    }
        return mosq;
    }
     

    // 初始化前如果是重连,不是第一次那么要先释放原来的内存。

    int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_start, void *userdata)
    {
        if(!mosq) return MOSQ_ERR_INVAL;

        if(clean_start == false && id == NULL){
            return MOSQ_ERR_INVAL;
        }

        mosquitto__destroy(mosq);
        memset(mosq, 0, sizeof(struct mosquitto));

        if(userdata){
            mosq->userdata = userdata;
        }else{
            mosq->userdata = mosq;
        }
        mosq->protocol = mosq_p_mqtt311;
        mosq->sock = INVALID_SOCKET;
        mosq->keepalive = 60;
        mosq->clean_start = clean_start;
        if(id){
            if(STREMPTY(id)){
                return MOSQ_ERR_INVAL;
            }
            if(mosquitto_validate_utf8(id, (int)strlen(id))){
                return MOSQ_ERR_MALFORMED_UTF8;
            }
            mosq->id = mosquitto__strdup(id);
        }
        mosq->in_packet.payload = NULL;
        packet__cleanup(&mosq->in_packet);
        mosq->out_packet = NULL;
        mosq->out_packet_count = 0;
        mosq->current_out_packet = NULL;
        mosq->last_msg_in = mosquitto_time();
        mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
        mosq->ping_t = 0;
        mosq->last_mid = 0;
        mosq->state = mosq_cs_new;
        mosq->max_qos = 2;
        mosq->msgs_in.inflight_maximum = 20;
        mosq->msgs_out.inflight_maximum = 20;
        mosq->msgs_in.inflight_quota = 20;
        mosq->msgs_out.inflight_quota = 20;
        mosq->will = NULL;
        mosq->on_connect = NULL;
        mosq->on_publish = NULL;
        mosq->on_message = NULL;
        mosq->on_subscribe = NULL;
        mosq->on_unsubscribe = NULL;

        mosq->host = NULL;
        mosq->port = 1883;
        mosq->in_callback = false;
        mosq->reconnect_delay = 1;
        mosq->reconnect_delay_max = 1;
        mosq->reconnect_exponential_backoff = false;
        mosq->threaded = mosq_ts_none;
    #ifdef WITH_TLS
        mosq->ssl = NULL;
        mosq->ssl_ctx = NULL;
        mosq->ssl_ctx_defaults = true;
        mosq->tls_cert_reqs = SSL_VERIFY_PEER;
        mosq->tls_insecure = false;
        mosq->want_write = false;
        mosq->tls_ocsp_required = false;
    #endif
    #ifdef WITH_THREADING
        pthread_mutex_init(&mosq->callback_mutex, NULL);
        pthread_mutex_init(&mosq->log_callback_mutex, NULL);
        pthread_mutex_init(&mosq->state_mutex, NULL);
        pthread_mutex_init(&mosq->out_packet_mutex, NULL);
        pthread_mutex_init(&mosq->current_out_packet_mutex, NULL);
        pthread_mutex_init(&mosq->msgtime_mutex, NULL);
        pthread_mutex_init(&mosq->msgs_in.mutex, NULL);
        pthread_mutex_init(&mosq->msgs_out.mutex, NULL);
        pthread_mutex_init(&mosq->mid_mutex, NULL);
        mosq->thread_id = pthread_self();
    #endif
        /* This must be after pthread_mutex_init(), otherwise the log mutex may be
         * used before being initialised. */
        if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){
            log__printf(mosq, MOSQ_LOG_WARNING,
                    "Warning: Unable to open socket pair, outgoing publish commands may be delayed.");
        }

        return MOSQ_ERR_SUCCESS;
    }
     

    更多相关内容
  • mosquitto库.rar

    2020-08-15 11:14:56
    经过编译以后,我们在/openwrt-hiwooya/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/mosquitto-nossl/mosquitto-1.4.10/lib这个目录下找到libmosquitto.a这个静态,在/openwrt-hiwooya/build_dir/target-...
  • 文章目录常用函数1、mosquitto_lib_init2、mosquitto_lib_cleanup3、mosquitto *mosquitto_new4、mosquitto_destroy5、mosquitto_username_pw_set6、mosquitto_connect7、mosquitto_disconnect8、mosquitto_publish9...

    今天列举的API是我在做项目过程中会使用到的,在该博客我将全部记录下来:

    常用函数

    1、mosquitto_lib_init

    int mosquitto_lib_init(void)

    函数功能: 使用mosquitto库函数前, 要先初始化, 使用之后需要清除。
    此函数不是线程安全的(线程安全:多个线程访问同一个对象时,调用这个对象的行为都可以获得正确的结果),也就是说mosquitto要第一个使用。

    返回值:总是MOSQ_ERR_SUCCESS

    2、mosquitto_lib_cleanup

    int mosquitto_lib_cleanup(void)

    作用:使用完mosquitto函数后,需要做清除工作

    返回值:总是MOSQ_ERR_SUCCESS

    3、mosquitto *mosquitto_new

    struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj)

    作用:创建一个新的mosquitto客户端实例

    参数:
    ①id:用作客户端id的字符串。如果为NULL, 生成一个随机的客户端id, 此时clean_session必须为true。

    ②clean_session: 若设置为true表示:代理(Broker)在断开时,客户端清除所有的消息和订阅;设置为false表示保留它们,客户端永远不会在断开时丢弃自己传出的消息。

    ③obj:用户指针,将作为参数传递给指定的任何回调(回调参数)

    返回值:
    成功:返回结构mosquitto的指针
    失败:NULL

    查询errno以确定失败的原因:
    ENOMEM: 内存不足
    EINVAL: 输入参数无效

    4、mosquitto_destroy

    void mosquitto_destroy(struct mosquitto *mosq)

    作用: 用于释放与mosquitto客户端实例关联的内存

    参数: 有效的mosquitto实例,mosquitto_new()返回的mosq,客户端

    5、mosquitto_username_pw_set

    int mosquitto_username_pw_set(struct mosquitto * mosq, const char *username, const char *password )

    功能:为mosquitto实例配置用户名和密码,必须在调用mosquitto_connect之前调用这个参数。

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②username : 以字符串形式发送的用户名,或以NULL形式关闭认证

    ③password :以字符串形式发送的密码。 当用户名有效时,设置为NULL,以便只发送一个用户名。

    返回值:
    MOSQ_ERR_SUCCESS:成功
    MOSQ_ERR_INVAL:输入参数无效
    MOSQ_ERR_NOMEM:发生内存不足的情况

    6、mosquitto_connect

    int mosquitto_connect( struct mosquitto *mosq, const char *host, int port, int keepalive )

    功能:连接到MQTT代理(Broker)/服务器
    主题订阅要在连接服务器之后进行

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq,客户端

    ②host:服务器ip地址

    ③port:服务器的端口号

    ④keepalive: 保持连接的时间间隔,单位:秒
    如果在这段时间内没有其他消息交换,则代理应该将PING消息发送到客户端的秒数

    返回值:
    MOSQ_ERR_SUCCESS :成功
    MOSQ_ERR_INVAL :输入参数无效
    MOSQ_ERR_ERRNO :系统调用返回错误

    7、mosquitto_disconnect

    int mosquitto_disconnect( struct mosquitto *mosq )

    功能:断开代理与服务器的连接

    返回值:
    MOSQ_ERR_SUCCESS :成功。
    MOSQ_ERR_INVAL :输入参数无效。
    MOSQ_ERR_NO_CONN :客户端未连接到代理

    8、mosquitto_publish

    int mosquitto_publish( struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain)

    功能:发布主题

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②mid: 指向int的指针。如果不为NULL,则函数会将其设置为该特定消息的消息ID。然后可以将其与订阅回调一起使用,以确定何时发送消息
    注意:尽管MQTT协议不对Qos = 0 的消息使用消息ID,但libmosquitto为其分配了消息ID,以便可以使用此参数对其进行跟踪。

    ③topic: 要发布的主题,以null结尾的字符串

    ④payloadlen:主题消息的内容长度

    ⑤payload:主题消息的内容,指向要发送数据的指针;
    如果payloadlen > 0,其必须是有效的存储位置

    ⑥qos:消息服务质量,整数值0、1、2

    ⑦retain:是否要保留消息,true为保留,false为不保留

    返回值:
    MOSQ_ERR_SUCCESS :成功
    MOSQ_ERR_INVAL :输入参数无效
    MOSQ_ERR_NOMEM :发生内存不足的情况
    MOSQ_ERR_NO_CONN :客户端未连接到代理
    MOSQ_ERR_PROTOCOL:与代理进行通信时存在协议错误
    MOSQ_ERR_PAYLOAD_SIZE:payloadlen太大
    MOSQ_ERR_QOS_NOT_SUPPORTED:QoS大于代理支持的QoS
    MOSQ_ERR_MALFORMED_UTF8 :主题无效,则为UTF-8
    MOSQ_ERR_OVERSIZE_PACKET :结果包大于代理支持的包

    9、mosquitto_subscribe

    int mosquitto_subscribe( struct mosquitto *mosq, int *mid, const char *sub, int qos)

    功能:订阅主题

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②mid: 指向int的指针。如果不为NULL,则函数会将其设置为该特定消息的消息ID。然后可以将其与订阅回调一起使用,以确定何时发送消息

    ③sub:主题的消息ID

    ④qos:消息服务质量,整数值0、1、2

    返回值:
    MOSQ_ERR_SUCCESS :成功
    MOSQ_ERR_INVAL :输入参数无效
    MOSQ_ERR_NOMEM :发生内存不足的情况
    MOSQ_ERR_NO_CONN :客户端未连接到代理
    MOSQ_ERR_QOS_NOT_SUPPORTED:QoS大于代理支持的QoS
    MOSQ_ERR_MALFORMED_UTF8 :主题无效,则为UTF-8
    MOSQ_ERR_OVERSIZE_PACKET :结果包大于代理支持的包

    10、mosquitto_loop_start

    int mosquitto_loop_start( struct mosquitto * mosq )

    函数功能:网络事件循环处理函数,通过创建新的线程不断调用mosquitto_loop() 函数处理网络事件,不阻塞

    返回值:
    MOSQ_ERR_SUCCESS 成功。
    MOSQ_ERR_INVAL 如果输入参数无效。
    MOSQ_ERR_NOT_SUPPORTED 如果没有线程支持。

    11、mosquitto_loop_forever

    int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)

    功能:此函数在无限阻塞循环中调用loop(),对于只想在程序中运行MQTT客户端循环的情况,这很有用。
    如果服务器断开,该函数会重新连接;若在回调中调用mosquitto_disconnect()它将返回

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②timeout:超时之前,在select()调用中等待网络活动的最大毫秒数;
    设置为0为立刻返回,设置为负可使用默认值为1000ms。

    ③max_packets:该参数当前为使用,应设为1,以备来兼容

    返回值:
    MOSQ_ERR_SUCCESS :成功
    MOSQ_ERR_INVAL :输入参数无效
    MOSQ_ERR_NOMEM :发生内存不足的情况
    MOSQ_ERR_NO_CONN :客户端未连接到代理
    MOSQ_ERR_CONN_LOST:与代理的连接丢失
    MOSQ_ERR_PROTOCOL:与代理进行通信时存在协议错误
    MOSQ_ERR_ERRNO:系统调用发生错误。变量errno包含错误代码

    12、mosquitto_loop_stop

    int mosquitto_loop_stop( struct mosquitto *mosq, bool force )

    功能:网络事件阻塞回收结束处理函数,是线程客户端接口的一部分。
    调用一次可停止先前使用mosquitto_loop_start创建的网络线程;该调用将一直阻塞,直到网络线程结束。
    可以事先调用mosquitto_disconnect或将force参数设置为true,来使网络线程结束

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②force:
    设为true表示:强制取消线程;若设为false,则必须已经调用mosquitto_disconnect

    返回值:
    MOSQ_ERR_SUCCESS:成功
    MOSQ_ERR_INVAL:输入参数无效
    MOSQ_ERR_NOT_SUPPORTED:没有线程支持

    回调函数

    1、mosquitto_connect_callback_set

    void mosquitto_connect_callback_set( struct mosquitto *mosq, void (*on_connect )(struct mosquitto *mosq, void *obj, int rc) )

    功能: 连接确认回调函数, 当代理发送CONNACK消息以响应连接时, 将调用此方法完成某一功能

    参数:
    ①mosq: 有效的mosquitto实例,mosquitto_new()返回的mosq

    ②回调函数,示例如下
    void callback (struct mosquitto *mosq, void *obj, int rc)
    回调的参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②void *obj: 创建客户端时的回调参数(mosquitto_new中提供的用户数据)

    ③int rc: 0表示连接成功, 其他表示失败
    rc连接响应的返回码, 其中有:

    • 0-成功
    • 1-连接被拒绝(版本协议不可接受)
    • 2-连接被拒绝(通识符被拒绝)
    • 3-连接被拒绝(经纪人不可用)
    • 4-255(保留供将来使用)
    2、mosquitto_disconnect_callback_set

    void mosquitto_disconnect_callback_set( struct mosquitto *mosq, void (*on_disconnect )(struct mosquitto *mosq, void *obj, int rc) )

    功能: 断开连接回调函数,当代理收到DISCONNECT命令并断开与客户端的连接,将调用此方法

    参数:
    ①mosq: 有效的mosquitto实例,mosquitto_new()返回的mosq,客户端

    ②回调函数,示例如下:
    void callback (struct mosquitto *mosq, void *obj, int rc)
    回调的参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②void *obj: 创建客户端时的回调参数

    ③int rc: 0表示客户端已经调用mosquitto_disconnect
    任何其他值都表示:连接时意外断开的

    3、mosquitto_message_callback_set

    void mosquitto_message_callback_set( struct mosquitto *mosq, void (*on_message)(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) )

    功能:消息回调函数,收到订阅的消息后调用

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②回调函数,格式如下:
    void callback (struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
    回调的参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②obj:mosquitto_new()中提供的用户数据

    ③message:消息数据。回调完成后,mosquitto库将释放此变量和内存的关联,客户应复制其所需要的任何数据

    struct mosquitto_message{
    int mid; //消息序号ID
    char *topic; //主题
    void *payload; //主题内容, MQTT中有效载荷
    int payloadlen; //消息的长度,单位是字节
    int qos;//服务质量
    bool retain;//是否保留消息
    };

    4、mosquitto_subscribe_callback_set

    void mosquitto_subscribe_callback_set( struct mosquitto * mosq, void (*on_subscribe)(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) )

    功能: 设置订阅回调。当代理响应订阅请求时,将调用此方法

    参数:
    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②回调函数,格式如下:
    void callback (struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
    回调的参数:

    ①mosq:有效的mosquitto实例,mosquitto_new()返回的mosq

    ②void *obj: 创建客户端时的回调参数(mosquitto_new中提供的用户数据)

    ③mid:订阅消息的消息ID

    ④qos_count:授予的订阅数(grant_qos的大小)

    ⑤granted_qos:整数数组,指示每个订阅的已授予QoS。

    展开全文
  • 文章目录(1)mosquitto_lib_init(2)mosquitto_lib_cleanup(3)mosquitto_new(4)mosquitto_destroy(5)mosquitto_username_pw_set(6)mosquitto_connect(7)mosquitto_reconnect(8)mosquitto_disconnect(9...

    一、初始化和清理

    (1)mosquitto_lib_init

    int mosquitto_lib_init (NULL)
    

    作用:初始化mosquitto,必须在任何其他mosqtto函数前使用它。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_UNKNOWN:在 Windows 上,无法初始化套接字。

    (2)mosquitto_lib_cleanup

    int mosquitto_lib_cleanup (NULL)
    

    作用:调用以释放与库关联的资源。

    返回值:
    MOSQ_ERR_SUCCESS 总是

    二、客户端创建、销毁

    (1)mosquitto_new

    struct mosquitto *mosquitto_new(const 	char  *id, bool  clean_session, void  *obj)
    

    作用:创建一个新的 mosquitto 客户端实例。

    参数:
    id:用作客户端 ID 的字符串。如果为 NULL,将生成一个随机客户端 ID。如果 id 为 NULL,则 clean_session 必须为真。

    clean_session:设置为 true 指示代理在断开连接时清除所有消息和订阅。设置为 false 指示它保留它们,注意,客户端永远不会在断开连接时丢弃自己的传出消息。调用mosquitto_connect或mosquitto_reconnect将导致消息被重新发送。使用mosquitto_reinitialise将客户端重置为其原始状态。如果 id 参数为 NULL,则必须设置为 true。

    obj:将作为参数传递给任何指定回调的用户指针。为指向struct mosquitto结构体类型的指针。

    返回值:
    成功则指向struct mosquitto类型的指针。失败时为 NULL。可查询 errno 以确定失败的原因。

    ENOMEM 内存不足。
    无效输入参数的 EINVAL。

    (2)mosquitto_destroy

    void mosquitto_destroy(struct  mosquitto  *	mosq)
    

    作用:用于释放与 mosquitto 客户端实例关联的内存。

    参数:指向需要free 的 struct mosquitto指针。

    三、用户名和密码

    mosquitto_username_pw_set

    int mosquitto_username_pw_set(struct  mosquitto  *mosq, const  char  *username,
    const char  *password)
    

    作用:为 mosquitto 实例配置用户名和密码。默认情况下,不会发送用户名或密码。对于 v3.1 和 v3.1.1 客户端,如果 username 为 NULL,则忽略密码参数。这必须在调用mosquitto_connect之前调用。

    参数:
    mosq:一个有效的mosquitto实例
    username:要作为字符串发送的用户名,或 NULL 以禁用身份验证。
    password:作为字符串发送的密码。当用户名有效时设置为 NULL,以便仅发送用户名。

    返回值:

    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。

    四、连接、重新连接、断开连接

    (1)mosquitto_connect

    作用:连接到 MQTT 代理。该功能适用​​于使用所有 MQTT 协议版本的客户端。

    int mosquitto_connect(	struct 	mosquitto 	*mosq, const  char  *host, int  port, int  keepalive)
    

    参数:
    mosq:一个有效的mosquitto实例。
    host:要连接的代理的主机名或 IP 地址。
    port:要连接的网络端口。通常是 1883 。
    keepalive:如果在这段时间内(秒数)没有交换其他消息,代理应该向客户端发送 PING 消息。

    返回值:

    MOSQ_ERR_SUCCESS:连接成功。
    MOSQ_ERR_INVAL:如果输入参数无效,可以是以下任何一种:
    mosq == NULL
    host == 空
    port < 0
    keepalive < 5

    MOSQ_ERR_ERRNO:如果系统调用返回错误。变量 errno 包含错误代码,即使在 Windows 上也是如此。在Linux情况下使用 strerror(errno) 或在 Windows 上使用 FormatMessage()。

    (2)mosquitto_reconnect

    int mosquitto_reconnect(struct 	mosquitto 	*mosq)
    

    作用:重新连接到代理。此功能提供了一种在连接丢失后重新连接到代理的简单方法。它使用mosquitto_connect调用中提供的值。但不能在mosquitto_connect之前调用它。

    参数:
    mosq:一个有效的mosquitto实例。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。
    MOSQ_ERR_ERRNO:如果系统调用返回错误。变量 errno 包含错误代码,即使在 Windows 上也是如此。在Linux下可使用 strerror(errno) 或在 Windows 上使用 FormatMessage()获取错误。

    (3)mosquitto_disconnect

    int mosquitto_disconnect(struct  mosquitto  *mosq)
    

    作用:断开与代理的连接。该功能适用​​于使用所有 MQTT 协议版本的客户端。

    参数:
    mosq:一个有效的mosquitto实例

    返回值:

    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NO_CONN:如果客户端未连接到代理

    五、发布、订阅、取消订阅

    (1)mosquitto_publish

    int mosquitto_publish(struct 	mosquitto 	*mosq,
    int 			*mid,
    const 	char 	*topic,
    int 			payloadlen,
    const 	void 	*payload,
    int 			qos,
    bool 			retain)
    

    作用:发布关于给定主题的消息。该功能适用​​于使用所有 MQTT 协议版本的客户端。如果需要设置 MQTT v5 PUBLISH 属性,请改用mosquitto_publish_v5。

    参数:
    mosq:一个有效的mosquitto实例。
    mid:指向 int 的指针。如果不为 NULL,该函数会将其设置为此特定消息的消息 ID。然后可以将其与发布回调一起使用,以确定何时发送消息。请注意,尽管 MQTT 协议不对 QoS=0 的消息使用消息 ID,但 libmosquitto 会为它们分配消息 ID,以便可以使用此参数跟踪它们。
    topic:要发布到的主题的以 null 结尾的字符串。
    payloadlen:有效载荷的大小(字节)。有效值介于 0 和 268,435,455 之间。
    payload:有效载荷,指向要发送的数据的指针。如果 payloadlen > 0 这必须是一个有效的内存位置。
    qos:服务质量,整数值 0、1 或 2,指示要用于消息的服务质量。
    retain:保持,设置为 true 以使消息保留。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。
    MOSQ_ERR_NO_CONN:如果客户端未连接到代理。
    MOSQ_ERR_PROTOCOL:如果与代理通信时出现协议错误。
    MOSQ_ERR_PAYLOAD_SIZE:如果 payloadlen 太大。
    MOSQ_ERR_MALFORMED_UTF8:如果主题不是有效的 UTF-8
    MOSQ_ERR_QOS_NOT_SUPPORTED:如果 QoS 大于代理所支持的。
    MOSQ_ERR_OVERSIZE_PACKET:如果生成的数据包比代理支持的大。

    (2)mosquitto_subscribe

    int mosquitto_subscribe(struct 	mosquitto 	*mosq,
    int  		*mid,
    const char  *sub,
    int  		qos)
    

    作用:
    订阅一个主题。该功能适用​​于使用所有 MQTT 协议版本的客户端。如果需要设置 MQTT v5 SUBSCRIBE 属性,请改用mosquitto_subscribe_v5。

    参数:
    mosq:一个有效的mosquitto实例。
    mid:指向 int 的指针。如果不为 NULL,该函数会将其设置为此特定消息的消息 ID。然后可以将其与 subscribe 回调一起使用,以确定消息何时发送。
    sub:订阅模式。
    qos:服务质量,此订阅请求的服务质量。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。
    MOSQ_ERR_NO_CONN:如果客户端未连接到代理。
    MOSQ_ERR_MALFORMED_UTF8:如果主题不是有效的 UTF-8
    MOSQ_ERR_OVERSIZE_PACKET:如果生成的数据包比代理支持的大。

    (3)mosquitto_unsubscribe

    int mosquitto_unsubscribe(struct mosquitto  *mosq,
    int  		*mid,
    const char 	*sub)
    

    作用:退订主题。

    参数:
    mosq:一个有效的mosquitto实例。
    mid:指向 int 的指针。如果不为 NULL,该函数会将其设置为此特定消息的消息 ID。然后可以将其与取消订阅回调一起使用,以确定消息何时发送。
    sub:退订模式。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。
    MOSQ_ERR_NO_CONN:如果客户端未连接到代理。
    MOSQ_ERR_MALFORMED_UTF8:如果主题不是有效的 UTF-8
    MOSQ_ERR_OVERSIZE_PACKET:如果生成的数据包比代理支持的大。

    六、网络循环(由 libmosquitto 管理)

    必须定期调用内部网络循环。两种推荐的方法是使用mosquitto_loop_forever或mosquitto_loop_start。 mosquitto_loop_forever是一个阻塞调用,适用于你只想在回调中处理传入消息的情况。 mosquitto_loop_start是一个非阻塞调用,它创建一个单独的线程来为您运行循环。当您需要与 MQTT 客户端同时运行其他任务时使用此功能,例如从传感器读取数据

    (1)mosquitto_loop_forever

    int mosquitto_loop_forever(struct mosquitto  *mosq,
    int  timeout,
    int  max_packets)
    

    此函数在无限阻塞循环中为您调用 loop()。这对于您只想在程序中运行 MQTT 客户端循环的情况很有用。

    **如果服务器连接丢失,它会处理重新连接。**如果您在回调中调用 mosquitto_disconnect(),它将返回。

    参数:
    mosq:一个有效的mosquitto实例。
    timeout:在超时之前等待 select() 调用中的网络活动的最大毫秒数。设置为 0 以立即返回。设置负数以使用默认值 1000 毫秒。
    max_packets:此参数当前未使用,应设置为 1 以便将来兼容。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。
    MOSQ_ERR_NO_CONN:如果客户端未连接到代理。
    MOSQ_ERR_CONN_LOST:如果与代理的连接丢失。
    MOSQ_ERR_PROTOCOL:如果与代理通信时出现协议错误。
    MOSQ_ERR_ERRNO:如果系统调用返回错误。变量 errno 包含错误代码,即使在 Windows 上也是如此。在Linux下使用 strerror(errno) 或在 Windows 上使用 FormatMessage()获取。

    (2)mosquitto_loop_start

    int mosquitto_loop_start( struct mosquitto *mosq)

    作用:
    这是线程客户端接口的一部分。调用一次以启动一个新线程来处理网络流量。这为重复调用mosquitto_loop提供了一种替代方法。

    参数:
    mosq:一个有效的mosquitto实例。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOT_SUPPORTED:如果线程支持不可用。

    (3)mosquitto_loop_stop

    int mosquitto_loop_stop(struct 	mosquitto 	*mosq, bool  force)
    

    作用:
    这是线程客户端接口的一部分。调用一次以停止先前使用mosquitto_loop_start创建的网络线程。此调用将阻塞,直到网络线程完成。要结束网络线程,您必须先前已调用mosquitto_disconnect或已将 force 参数设置为 true。

    参数:
    mosq:一个有效的mosquitto实例。
    force:设置为 true 以强制取消线程。如果为 false,则 mosquitto_disconnect必须已被调用。

    返回值:
    MOSQ_ERR_SUCCESS:成功。
    MOSQ_ERR_INVAL:输入参数无效。
    MOSQ_ERR_NOT_SUPPORTED:线程支持不可用。

    (4)mosquitto_loop

    int mosquitto_loop(struct 	mosquitto 	*	mosq,
    int 		timeout,
    int 		max_packets)
    

    作用:
    客户端的主网络循环。必须经常调用它以保持客户端和代理之间的通信正常工作。这是由mosquitto_loop_forever和mosquitto_loop_start 执行的,它们是处理网络循环的推荐方法。如果您愿意,也可以使用此功能。不能在回调中调用它。
    如果存在传入数据,则将对其进行处理。传出命令,例如 mosquitto_publish,通常在调用它们的函数时立即发送,但这并不总是可能的。 mosquitto_loop还将尝试发送任何剩余的传出消息,其中还包括作为 QoS>0 消息流的一部分的命令。
    这调用 select() 来监视客户端网络套接字。如果您想将 mosquitto 客户端操作与您自己的 select() 调用集成,请使用mosquitto_socket、mosquitto_loop_read、mosquitto_loop_write和mosquitto_loop_misc。

    参数:
    mosq:一个有效的mosquitto实例。
    timeout:在超时之前等待 select() 调用中的网络活动的最大毫秒数。设置为 0 以立即返回。设置负数以使用默认值 1000 毫秒。
    max_packets:此参数当前未使用,应设置为 1 以便将来兼容。

    返回值:
    MOSQ_ERR_SUCCESS:关于成功。
    MOSQ_ERR_INVAL:如果输入参数无效。
    MOSQ_ERR_NOMEM:如果发生内存不足的情况。
    MOSQ_ERR_NO_CONN:如果客户端未连接到代理。
    MOSQ_ERR_CONN_LOST:如果与代理的连接丢失。
    MOSQ_ERR_PROTOCOL:如果与代理通信时出现协议错误。
    MOSQ_ERR_ERRNO:如果系统调用返回错误。变量 errno 包含错误代码,即使在 Windows 上也是如此。在Linux下使用 strerror(errno) 或在 Windows 上使用 FormatMessage()获取。

    七、回调

    (1)mosquitto_connect_callback_set

    void mosquitto_connect_callback_set(struct 	mosquitto  *mosq,
    void (*on_connect)(struct mosquitto *, void *, int))
    

    作用:
    设置连接回调。这在代理发送 CONNACK 消息以响应连接时调用。

    参数:
    mosq:一个有效的mosquitto实例。
    on_connect:函数指针,以下形式的回调函数: void callback(struct mosquitto *mosq, void *obj, int rc),在使用编写此回调函数时,一定要严格安装此参数和类型的要求。

    回调参数
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    rc:连接响应的返回码。这些值由使用的 MQTT 协议版本定义。

    (2)mosquitto_disconnect_callback_set

    void mosquitto_disconnect_callback_set(struct 	mosquitto *mosq,
    void  (*on_disconnect)(struct mosquitto *, void *, int))
    

    作用:设置断开回调。当代理收到 DISCONNECT 命令并断开客户端的连接时调用。

    参数:
    mosq:一个有效的mosquitto实例。
    on_disconnect:以下形式的回调函数:void callback(struct mosquitto *mosq, void *obj)

    回调参数:
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    rc:指示断开连接原因的整数值。值 0 表示客户端已调用mosquitto_disconnect。任何其他值表示断开是意外的。

    (3)mosquitto_publish_callback_set

    void mosquitto_publish_callback_set(struct 	mosquitto  *mosq,
    void (*on_publish)(struct mosquitto *, void *, int))
    

    作用:
    设置发布回调。当使用mosquitto_publish启动的消息已成功发送到代理时,将调用此方法。

    参数:
    mosq:一个有效的mosquitto实例。
    on_publish:以下形式的回调函数: void callback(struct mosquitto *mosq, void *obj, int mid)

    回调参数:
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    mid:已发送消息的消息 ID。

    (4)mosquitto_message_callback_set

    void mosquitto_message_callback_set(struct 	mosquitto 	*mosq,
    void  (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *))
    

    作用:
    设置消息回调。当从代理接收到消息时调用它。

    参数:
    mosq:一个有效的mosquitto实例。
    on_message:以下形式的回调函数:void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)

    回调参数:
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    message:消息数据。回调完成后,该变量和关联的内存将由库释放。客户应该复制它需要的任何数据。

    (5)mosquitto_subscribe_callback_set

    void mosquitto_subscribe_callback_set(struct  mosquitto 	*mosq,
    void  (*on_subscribe)(struct mosquitto *, void *, int, int, const int *))
    

    作用:
    设置订阅回调。当代理响应订阅请求时调用。

    参数:
    mosq:一个有效的mosquitto实例。
    on_subscribe:以下形式的回调函数: void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)

    回调参数:
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    mid:订阅消息的消息 ID。
    qos_count:授予订阅的数量(granted_qos 的大小)。
    grant_qos:一个整数数组,指示每个订阅的授予 QoS。

    (6)mosquitto_unsubscribe_callback_set

    void mosquitto_unsubscribe_callback_set(struct 	mosquitto 	*mosq,
    void (*on_unsubscribe)(struct mosquitto *, void *, int))
    

    作用:
    设置取消订阅回调。当代理响应取消订阅请求时调用它。

    参数:
    mosq:一个有效的mosquitto实例。
    on_unsubscribe:以下形式的回调函数: void callback(struct mosquitto *mosq, void *obj, int mid)

    回调参数:
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    mid:取消订阅消息的消息 ID。

    (7)mosquitto_log_callback_set

    void mosquitto_log_callback_set(struct 	mosquitto 	*mosq,
    void (*on_log)(struct mosquitto *, void *, int, const char *))
    

    作用:
    设置日志记录回调。如果您需要来自客户端库的事件日志信息,则应使用此选项。

    清真寺 一个有效的mosquitto实例。
    on_log 以下形式的回调函数: void callback(struct mosquitto *mosq, void *obj, int level, const char *str)

    回调参数:
    mosq:进行回调的 mosquitto 实例。
    obj:mosquitto_new中提供的用户数据
    level:来自值的日志消息级别: MOSQ_LOG_INFO、 MOSQ_LOG_NOTICE、 MOSQ_LOG_WARNING、 MOSQ_LOG_ERR、 MOSQ_LOG_DEBUG
    str:消息字符串。

    八、实用功能

    mosquitto_strerror

    const char *mosquitto_strerror(int 	mosq_errno)
    

    作用:
    调用以获取 mosquitto错误号的 const 字符串描述。

    参数:
    mosq_errno :mosquitto错误编号。

    返回值:
    描述错误的常量字符串。

    九、常见的返回值

    MOSQ_ERR_INVAL=3
    MOSQ_ERR_NOMEM=1
    MOSQ_ERR_NO_CONN=4
    MOSQ_ERR_MALFORMED_UTF8=18
    MOSQ_ERR_OVERSIZE_PACKET=25
    MOSQ_ERR_CONN_LOST=7 //如果与代理的连接丢失
    MOSQ_ERR_PROTOCOL=2 //如果与代理通信时出现协议错误
    MOSQ_ERR_ERRNO=14

    展开全文
  • 在学习此之前,我们要先明白iniparser以及cJSON,为什么要学习这个呢?首先iniparser可以对ini文件进行解析、设置、删除等操作,我们知道当我们与阿里云进行通信时,需要很多参数,比如要知道阿里云的域名,...

    我们先看一下搭建mqtt的基本流程图吧(不是项目的流程图,我简单画的一个)。
    在这里插入图片描述
    关于调用mosquitto库中的函数的学习,可以参考一下我写的常见mosquitto库中函数的学习:https://blog.csdn.net/makunIT/article/details/107283260

    在写代码的时候,我用到了iniparser库和cJSON库,我们要先明白iniparser库以及cJSON库,为什么要学习这个呢?首先iniparser库可以对ini文件进行解析、设置、删除等操作,我们知道当我们与阿里云进行通信时,需要很多参数,比如要知道阿里云的域名,端口、以及username、passwd、客户端id以及发布的主题、服务质量都需要进行配置,所以使用iniparsesr库可以解决很多配置的问题。如下图是我写的ini文件
    在这里插入图片描述
    关于iniparser库的学习可以参考以下我之前写的博客,博客链接为:
    https://blog.csdn.net/makunIT/article/details/107209915

    那么我们为什么还需要学习cJSON库那,cJSON是一个超轻巧,携带方便,单文件,简答的可以作为ANSI-C标准的解析器。而json是一种在服务器端和客户端交换数据的轻量级数据格式,而对于阿里云的上报会比较严格,还需要相同的json格式发布阿里云平台才能收到,而cJSON库的使用可以创建josn格式的数据。
    关于cJSON的学习可以参考一下我的博客:https://blog.csdn.net/makunIT/article/details/107199000
    在这里插入图片描述
    以上是我创建的json格式的数据,我们将把这个消息发送给阿里云。

    我们先来看一下我这段代码的作用,这段代码是我写的通过传参的形式来配置连接阿里云之间的通信的,为什么我们用ini文件配置了为什么还要传连接时候的参数那,因为这样可以实现代码的利用率,这样我们再阿里云再创建一个设备时,我们可以直接通过参数来连接阿里云,这样也会更加方便一点。

    int set_mqtt_conf(char *path_ini, char *host, int port, char *clientid, char *user, char *passwd, char *topic)
    {
        FILE        *fp = NULL;
        dictionary  *ini = NULL;
        char        * mqtt_port;
        char          mqtt_pot[16];
    
        if(port)
        {
            snprintf(mqtt_pot, sizeof(mqtt_pot), "%d" , port);
            mqtt_port = mqtt_pot;
        }
    
        ini = iniparser_load(path_ini);
    
        if(ini == NULL)
        {
            printf("iniparser failure \n");
            return -1;
        }
        /*配置参数*/
        iniparser_set(ini, "aly_address:host", host);
        iniparser_set(ini, "aly_address:port", mqtt_port);
        iniparser_set(ini, "clientId:id", clientid);
        iniparser_set(ini, "user_passwd:username", user);
        iniparser_set(ini, "user_passwd:passwd", passwd);
        iniparser_set(ini, "pub_topic:topic", topic);
        /*有些参数后面再配置*/
    
        fp = fopen(path_ini, "w");
        if(fp == NULL)
        {
            printf("stone: fopen error!\n");
            return -2;
        }
        
        iniparser_dump_ini(ini, fp);
    
        iniparser_freedict(ini);
    
        return 0;
    }
    

    在这里插入图片描述
    我们再来看这段代码,这段代码的功能就是解析ini文件,实现连接阿里云,实现两者的通信,我们使用iniparser库获取ini文件的配置,然后填充结构体,此结构体的内容将会在发布的时候要用到。

    int gain_mqtt_conf(char *path_ini, mqtt_ctx_t *mqtt)
    {
        dictionary    *ini = NULL;
        const char    *hostname;
        int           port;
        const char    *username;
        const  char   *passwd;
        const  char   *clientid;
        const  char   *pubTopic;
        int           pubQos;
        int           keepalive;
    
        const   char *method;
        const   char *id;
        const   char *identifier;
        const   char *version;
    
        if(!path_ini || !mqtt)
        {   
            printf("Invalid input argument in %s!\n",__FUNCTION__);
            return -1; 
        }   
    
        /* 加载配置文件,将数据存于dictionary结构中*/
        ini = iniparser_load(path_ini);
        if(ini == NULL)
        {   
            printf("iniparser_load failure!\n");
            return -2; 
        }
    
    
        /*获取字符串,若未找到返回第三个参数的内容*/
        hostname = iniparser_getstring(ini,"aly_address:host", DEF_BORKER_HOSTNAME);
        port = iniparser_getint(ini,"aly_address:port", DEF_BORKER_PORT);
    
        username = iniparser_getstring(ini, "user_passwd:username", DEF_BORKER_USERNAME);
        passwd = iniparser_getstring(ini, "user_passwd:passwd", DEF_BORKER_PASSWD);
    
        clientid = iniparser_getstring(ini, "clientId:id",DEF_BORKER_CLIENTID );
    
        pubTopic = iniparser_getstring(ini, "pub_topic:topic", DEF_BORKER_PUBTOPIC);
    
    
        pubQos = iniparser_getint(ini, "aly_Qos:QoS", DEF_PUBQOS);
    
        keepalive = iniparser_getint(ini, "KEEP_ALIVE:alive",DEF_BROKER_KEEPALIVE);
    
        method = iniparser_getstring(ini, "aly_json:method",DEF_METHOD);
        id = iniparser_getstring(ini, "aly_json:id",DEF_ID);
        identifier = iniparser_getstring(ini, "aly_json:identifier",DEF_IDENTIFIER);
        version = iniparser_getstring(ini, "aly_json:version",DEF_VERSION);
    
        strncpy(mqtt->method, method, sizeof(mqtt->method));
        strncpy(mqtt->id, id, sizeof(mqtt->method));
        strncpy(mqtt->identifier, identifier,sizeof(mqtt->identifier));
        strncpy(mqtt->version, version, sizeof(mqtt->version));
    
    
    
        /*  Broker settings  */
        strncpy(mqtt->hostname, hostname, sizeof(mqtt->hostname) );
        mqtt->port = port;
        printf("Use default broker server [%s:%d]\n", mqtt->hostname, mqtt->port);
    
        strncpy(mqtt->username, username, sizeof(mqtt->username) );
        strncpy(mqtt->passwd , passwd, sizeof(mqtt->passwd) );
        printf("Use default broker author by [%s:%s]\n", mqtt->username, mqtt->passwd);
    
        mqtt->keepalive= keepalive;
        printf("Use default broker keepalive timeout [%d] seconds\n", mqtt->keepalive);
    
        /*  Publisher settings  */
        strncpy(mqtt->pubTopic, pubTopic, sizeof(mqtt->pubTopic));
        mqtt->pubQos = pubQos;
        printf( "Use default publisher topic \"%s\" with Qos[%d]\n",mqtt->pubTopic, mqtt->pubQos);
    
        strncpy(mqtt->clientid,  clientid, sizeof(mqtt->clientid));
    
        /*释放dictionary对象/内存*/
        iniparser_freedict(ini); 
    
        return 0;
    
    }
    

    以下代码是搭建客户端的主函数,此函数主要用mosquitto库里面的函数,连接阿里云然后发送JSON格式的数据,实现将客户端发布的数据,显示到阿里云平台上面。

    /*********************************************************************************
     *      Copyright:  (C) 2020 makun<1394987689@qq.com>
     *                  All rights reserved.
     *
     *       Filename:  mosquitto_pub.c
     *    Description:  This file 
     *                 
     *        Version:  1.0.0(2020年07月08日)
     *         Author:  makun <1394987689@qq.com>
     *      ChangeLog:  1, Release initial version on "2020年07月08日 22时30分04秒"
     *                 
     ********************************************************************************/
    
    
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>
    #include <libgen.h>
    #include <getopt.h>
    #include <string.h>
    #include <mosquitto.h>
    #include <stdlib.h>
    
    #include "conf.h"
    #include "cJSON.h"
    
    
    #define  PROG_VERSION "1.0.0"
    #define  PATH_INT "./mqtt_aly_conf.ini"
    
    void pub_conn_callback(struct mosquitto *mosq, void *obj, int rc);
    static void  print_usage( char *progname)
    {
        printf("Usage  %s [option]...\n", progname);
        printf("%s is makun studi MQTT daemon program running on RaspberryPi\n", progname);
    
        printf("-p (--port):   the port of the server you want to connect\n");
        printf("-h (--host):   the hostname of the server you want to connect\n");
        printf("-u (--user):   the username of the client\n");
        printf("-P (--passwd): the passwd of the client you\n");
        printf("-i (--clientid): the clientid of the user\n");
        printf("-t (--topic):  the topic of the client you want to pub\n");
        printf("-H (--help): Display this help information\n");
        printf("-v (--version): Display the program version\n");
    
        printf("%s  Version %s\n", progname, PROG_VERSION);
        return ;
    }
    
    int main (int argc, char **argv)
    {
        char         *host = NULL;
        int          port ;
        char         *clientid = NULL;
        char         *user = NULL;
        char         *passwd = NULL;
        char         *topic = NULL;
        int          rv = -1;
        int          opt= -1;
        char         *progname = NULL;
        bool         session = true;
        mqtt_ctx_t   mqtt;
    
        struct mosquitto *mosq = NULL;
    
        
        struct option long_options[]= {
            {"host", required_argument, NULL, 'h'},
            {"port", required_argument, NULL, 'p'},
            {"user", required_argument, NULL, 'u'},
            {"passwd",required_argument, NULL,'P'},
            {"topic", required_argument, NULL, 't'},
            {"clientid", required_argument, NULL, 'i'},
            {"help", no_argument, NULL, 'H'},
            {"version", no_argument, NULL, 'v'},
            {0, 0, 0, 0}
        };
    
        progname = (char *)basename(argv[0]);
    
        while( (opt = getopt_long(argc, argv,"h:p:u:P:i:tHv", long_options,NULL)) != -1)
        {
            switch (opt)
            {
                case 'h':
                    host = optarg;
                    break;
                case 'p':
                    port = atoi(optarg);
                    break;
                case 'u':
                    user = optarg;
                    break;
                case 'P':
                    passwd = optarg;
                    break;
                case 'i':
                    clientid = optarg;
                case 't':
                    topic = optarg;
                    break;
                case 'v':
                    printf("%s Version %s\n",progname, PROG_VERSION);
                    return 0;
                case 'H':
                    print_usage(progname);
                    return 0;
                default:
                    break;
            }
        }
    
        rv=set_mqtt_conf(PATH_INT, host, port, clientid, user,passwd, topic);
        if(rv < 0)
        {
            printf("set mqtt conf is failure %d\n", rv);
            return -1;
        }
    
        memset(&mqtt, 0, sizeof(mqtt));
    
        rv = gain_mqtt_conf(PATH_INT, &mqtt);
        if(rv < 0)
        {
            printf("gain mqtt conf failure %d\n", rv);
            return -2;
        }
    
        /*必须在任何其他mosquitto功能之前调用*/
        mosquitto_lib_init();
    
        /*创建一个新的mosquitto客户端实例,第二个参数为true,代理清除断开连接时的所有消息和订阅*/
        mosq = mosquitto_new(mqtt.clientid,session, (void *)&mqtt );
        if(!mosq)
        {
            printf("mosquitto new failure: %s\n", strerror(errno));
            goto cleanup;
        }
    
        printf("Create mosquitto successfuly\n");
    
        /*设置连接回调,当代理发送CONNACK消息以响应连接时,将调用此方法*/
        mosquitto_connect_callback_set(mosq, pub_conn_callback);
    
    
        /*配置mosquitto实例的用户名和密码*/
        if( mosquitto_username_pw_set(mosq, mqtt.username,mqtt.passwd) !=MOSQ_ERR_SUCCESS)
        {
            printf("mosquitto username and passwd failure:%s\n",strerror(errno));
            goto cleanup;
        }
    
        while(1)
        {
            /*连接MQTT代理*/
            if(mosquitto_connect(mosq, mqtt.hostname, mqtt.port, mqtt.keepalive) != MOSQ_ERR_SUCCESS )
            {
                printf("mosquitto connect server failure:%s\n",strerror(errno));
                continue;
                sleep(1);
            }
    
            /*无线阻塞循环调用loop*/
            mosquitto_loop_forever(mosq, -1, 1 );
            sleep(10);
        }
    
    cleanup:
        printf("program will exit\n");
        mosquitto_destroy(mosq);
        mosquitto_lib_cleanup();
    
        return 0;
    
    }
    
    
    void pub_conn_callback(struct mosquitto *mosq, void *obj, int rc)
    {
        mqtt_ctx_t  *mqtt;
        int mid;
        char    *msg;
        cJSON   *root = cJSON_CreateObject();
        cJSON   *item = cJSON_CreateObject();
        int     retain = 0;
        char    *payload = "moquitto test aly";
    
        if(!mosq ||!obj)
        {
            printf("invalid input argument\n");
            return ;
        }
        mqtt = (mqtt_ctx_t *)obj;
    
        cJSON_AddItemToObject(root, "method", cJSON_CreateString(mqtt->method));//根节点下添加
        cJSON_AddItemToObject(root, "id", cJSON_CreateString(mqtt->id));//根节点下添加
        cJSON_AddItemToObject(root, "params",item);
        cJSON_AddItemToObject(item, mqtt->identifier, cJSON_CreateString(payload));
        cJSON_AddItemToObject(root, "version", cJSON_CreateString(mqtt->version));
        
        msg = cJSON_Print(root);
        printf("%s\n", msg);
    
        if(!rc)
        {  
            if( mosquitto_publish(mosq,&mid,mqtt->pubTopic,strlen(msg)+1, msg, mqtt->pubQos, retain) != MOSQ_ERR_SUCCESS )  
            {   
                printf("Mosq_Publish() error: %s\n", strerror(errno));
                return ;
            }
            printf("pubilush topic:%s\n",mqtt->pubTopic) ;
        }
        mosquitto_disconnect(mosq) ;
    
    }
    
    

    我们打开阿里云平台上的在线调试。
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    这样我们就成功实现了客户端到服务器端的通信,以上,只是我写的一个测试的例子,接下来,我将学习SHT20获取温度,然后通过mqtt客户端发布温度,阿里云能够实时监控到温度的一个学习,感兴趣的可以关注一下我的博客,我们一起学习。

    编程源码链接:https://gitee.com/ma_kung/mqtt

    展开全文
  • 物联网mosquitto库应用,客户端测试, qtcreator5.11 编译。具体见说明文档。源代码+可执行应用程序。对使用mosquitto开发初学者,可做适当参考。
  • mosquitto库常用的相关函数解析

    千次阅读 2022-04-17 16:03:17
    注:此头文件用于包含libmosquitto(Mosquitto客户端)的函数和定义。该提供线程安全操作,但mosquitto_lib_init除外,它不是线程安全的。 mosquitto_lib_init() int mosquitto_lib_init(void) 功能描述:在...
  • 6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制 (以上摘自百度百科) 移植mosquitto库用于ARM开发板连接平台服务器,上传数据。移植的mosquitto是1.6.9版本,该版本支持5.0、3.1.1、3.1版本...
  • 二.iniparser介绍三.CJSON介绍四.需要使用到的文件五.流程图六.代码实现测试 一.连接阿里云服务器测试 mqtt.fx测试与阿里云平台的连通。 可以参考博客 mqtt.fx实现与阿里云的通信 主要是记录一下mqtt连接参数和...
  • Linux C MQTT上报温度到腾讯云(基于mosquitto库) 一、创建产品 1.进入腾讯云官网,登陆或注册账号 2.进入控制台 3.鼠标滑到云产品,进入物联设备服务中的物联网通信 4.点击创建新产品,现在我们来创建一个上报...
  • 一、MQTT简介 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/...Mosquitto是一个实现了MQTT3.1协议的代理服务器,由MQTT协议创始人之一的Andy Stanford-Clark开发,应用广泛的低功耗传感器,手...
  • MQTT简介:https://www.runoob.com/w3cnote/mqtt-intro.html 二.mosquitto库 mosquitto是一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备...
  • mosquitto之arm编译

    2021-01-06 03:46:26
     请安装arm交叉编译工具链,然后参考mosquitto之linux编译中CMake的使用方法,注意需要修改如下配置选项: CMAKE_AR,指定到交叉编译工具链中的ar程序,例如:/home/crosstool/sysroots/x86_64-oesdk-linux/usr/bin...
  • 在用mosquitto的时候,发现使用到该已定义的结构体,为了更好地了解mosquitto的使用,参考别人的博客,作了下面笔记,如侵,则删。另外,所列举的结构体成员为常用的成员,尚未列举完,请注意! 文章目录一、...
  • mosquitto库实现发布与订阅一、下载安装mosquitto二、mosquitto发布与订阅三、mosquitto运行实例 一、下载安装mosquitto (1)下载地址:https://mosquitto.org/download/ Linux命令行输入 wget ...
  • MQTT–利用mosquitto库多线程实现sub端和pub端 1.关于mqtt的介绍以及mosquitto的基本使用相信大家都已经有所了解;有时候我们想写一个程序,既可以实现订阅(sub端),又可以做别的事情,比如读取并且处理一些传感器...
  • 目录mosquitto库简介:使用到的mosquitto库提供的API使用到的cJSON库提供的API源码: mosquitto库简介: 使用到的mosquitto库提供的API 这里我只列出了我使用到的函数 这里面的参数和返回值以及具体的用法我想大家...
  • mosquitto库中常见的函数应用总结

    千次阅读 2020-07-11 15:18:31
    1、int mosquitto_lib_init(void) 功能:使用mosquitto库函数前,要先初始化,使用之后就要清除。清除函数;int mosquitto_lib_cleanup(); 返回值:MOSQ_ERR_SUCCESS 总是 2、int mosquitto_lib_cleanup(void) ...
  • 这里做的是上报阿里云平台 ...接下来就用mosquitto库自己实现mqtt客户端 使用了开源的iniparser库来操作配置文件,对于这些需要很多参数的程序,用一个配置文件来解决就很方便,可以了解一下iniparser库: ...
  • mosquitto库的使用记录

    千次阅读 2021-11-01 15:49:30
    本文记录了使用mosquitto库实现MQTT协议通信的发布端及常见错误的解决方法 订阅端的测试工具为MQTT.fx 下载链接链接:https://pan.baidu.com/s/1ztWGXbrLAqCoMoJKpwO7yg 提取码:mu8v MQTT 是一种基于发布/订阅...
  • mosquitto 2.x的安装问题和mosquitto库的使用 Linux C如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX...
  •   本篇博客将是本项目的最后一篇博客,为了拓展自己的知识面,除了本博客树莓派使用mosquitto库上阿里云外,我还实现了树莓派+paho库上华为云。在此之前请看完以下几篇博客: ①项目准备一之CJSON学习 ...
  • 目录 1,首先在腾讯云上创建产品 2,通过mosquitto库命令与腾讯云通信 1,首先在腾讯云上创建产品 进入腾讯云官网,找到控制台,搜索物联网开发平台 进去后选择IoT Hub 再点击创建产品 填好产品名称,选择密钥认证,...
  • mosquitto_connect(mosq, serv_ip, port, 60) mosquitto_publish(mosq, NULL, topic, strlen(payload)+1, payload, 0, 0); 2.在Linux下使用我们写的MQTT客户端连接阿里云并上报温度 3.客户端运行成功后回到阿里云的...
  • 1、在Linux下的服务器需要订阅消息,阿里云才能给其发布消息,订阅命令与阿里云控制台的设备信息有关(详细请看上一篇博客mosquitto安装): 以上是在阿里云控制台双肩设备的时候保存下来的信息,Linux下订阅消息的...
  • 做这项工作之前,我已经做了一些准备工作了,我之前写的 “基于mosquitto库搭建mqtt客户端发布实现与阿里云的通信”以及“基于树莓派3B SHT20温湿度采样”都是为此项目做好准备的,大家如果想要完成树莓派与阿里云的...
  • Moswuitto Mosquitto基本API 常用函数介绍 C编程实现代码 Head File C Source File Make File 测试案例 连接前 阿里云设备状态 连接后 运行程序 阿里云设备运行状态 ​ 发送下行消息 运行结果 ...
  • char *payload = "{\"services\": [{\"service_id\": \"1\",\"properties\": {\"CurrentTemperature\": 21.5}}]}" mosq = mosquitto_new(clientId, ture, NULL); mosquitto_username_pw_set(mosq, username, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,762
精华内容 704
关键字:

mosquitto库