利用mosquitto库上报数据到阿里云——C语言编程

目录

mosquitto库简介:

使用到的mosquitto库提供的API

这里我只列出了我使用到的函数
这里面的参数和返回值以及具体的用法我想大家百度就可以很容易知道了
要了解更多可以参考:https://mosquitto.org/api/files/mosquitto-h.html

mosquitto_lib_init()                //Must be called before any other mosquitto functions.
mosquitto_new()                     //Create a new mosquitto client instance.
mosquitto_username_pw_set()         //Configure username and password for a mosquitto instance.
mosquitto_connect()                 //Connect to an MQTT broker.
mosquitto_connect_callback_set()    //Set the connect callback.
mosquitto_loop_forever()            //This function call loop() for you in an infinite blocking loop.
mosquitto_publish()                 //Publish a message on a given topic.
mosquitto_disconnect()              //Disconnect from the broker.
mosquitto_destroy()                 //Use to free memory associated with a mosquitto client instance.
mosquitto_lib_cleanup()             //Call to free resources associated with the library.

我使用的是短连接,所以每一次发送完数据都会调用mosquitto_disconnect()

使用到的cJSON库提供的API

通过MQTT协议上报数据到阿里云数据格式是JSON格式,所以我们要用到cJSON库,把我们要发送的数据打包成JSON格式。
下载编译好cJSON库之后,我们可以直接使用其目录下的cJSON.c和cJSON.H文件进行编程
所以的cJSON函数定义在cJSON.c文中,在cJSON.h头文件中声明,想要了解更多的可以进去打卡看

 cJSON_CreateObject()//创建一个json对象,返回一个cJSON结构体类型的指针
 cjson_params()//添加一个嵌套的JSON数据
 cJSON_AddNumberToObject()
 cJSON_AddItemToObject ()
 cJSON_Print()
 cJSON_Delete()

源码:

.c 文件

/*********************************************************************************
 *      Copyright:  (C) 2021 li liangshi<1007146932@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  mosquitto_pub.c
 *    Description:  This file is mosquitto_pub to aliyun
 *                 
 *        Version:  1.0.0(2021年08月06日)
 *         Author:  li liangshi <1007146932@qq.com>
 *      ChangeLog:  1, Release initial version on "2021年08月06日 00时33分39秒"
 *                 
 ********************************************************************************/

#include "mosquitto_pub.h"

static int g_stop = 0;

void sig_handle(int signum)
{
	if(SIGUSR1 == signum)
	{
		g_stop = 1;
	}
}

int main (int argc, char **argv)
{
    struct mosquitto       *mosqut; 
    mosquitto_t             mosquitto;
    int                     rv = -1;
    
    memset(&mosquitto, 0, sizeof(mosquitto));

    rv = init_mosquitto_argc(argc, argv, &mosquitto);
    if(rv)
    {
		printf("Init mosquitto arguments error:%s\n", strerror(errno));
    }
	
    signal(SIGUSR1,sig_handle);
    
    rv = mosquitto_pub_start(mosqut, &mosquitto);
    if(rv)
    {
		printf("mosquitto subscribe start error:%s\n", strerror(errno)); 
    }

    return 0;
}


int init_mosquitto_argc (int argc, char **argv, mosquitto_t *mosquitto)
{
	if (argc < 0 )
		return -1;

	int   ch = -1; 

	struct option        opts[] = { 
		{"--host",      required_argument, NULL, 'H'},
		{"--port",      required_argument, NULL, 'p'},
		{"--topic",     required_argument, NULL, 't'},
		{"--client_id", required_argument, NULL, 'i'},
		{"--user",      required_argument, NULL, 'u'},
		{"--password",  required_argument, NULL, 'P'},
		{"--keepalive", required_argument, NULL, 'l'},
		{"help",        no_argument,       NULL, 'h'},    
		{NULL,          0,                 NULL,  0 }
	};  

	while((ch=getopt_long(argc, argv, "H:p:t:i:u:P:l:h", opts, NULL)) != -1 )    
	{   
		switch(ch)
		{   
			case 'H':   
				mosquitto->host = optarg;
				break;
			case 'p':
				mosquitto->port = atoi(optarg);
				break;
			case 't':
				mosquitto->topic = optarg;
				break;
			case 'i':
				mosquitto->client_id = optarg;
				break;
			case 'u':
				mosquitto->user = optarg;
				break;
			case 'P':
				mosquitto->password = optarg;
				break;
			case 'l':
				mosquitto->keepalive = atoi(optarg);
				break;
			case 'h':
				print_usage(argv[0]);
				return -1;
		}    
	}   


	if (NULL == mosquitto->host || !mosquitto->keepalive ||!mosquitto->port || NULL == mosquitto->client_id || NULL == mosquitto->password || NULL == mosquitto->user || NULL == mosquitto->topic)
	{
		print_usage(argv[0]);
		return -1;
	}

	return 0;
}


static void print_usage (char *progname)
{
	printf("%s usage : \n", progname);
	printf("-H(--host):Input the Aliyun equioment host name.\n");
	printf("-p(--port):Input the Aliyun equioment host port.\n");
	printf("-i(--client_id):Input the Aliyun equioment client id.\n");
	printf("-t(--topic):Input the Aliyun equioment subscribe topic.\n");
	printf("-u(--user):Input the Aliyun equioment user name.\n");
	printf("-P(--password):Input the Aliyun equioment user's password name.\n");
	printf("-l(--keepalive):Input the keepalive.\n");
	printf("-h(--help): print this help information.\n");

	return ;
} 


int mosquitto_pub_start (struct mosquitto *mosqut, mosquitto_t *mosquitto)
{
    int                     rv = 1;
    
    //初始化mosquitto lib
    rv = mosquitto_lib_init();
    if(rv != MOSQ_ERR_SUCCESS)
    {
        printf("mosquitto lib init failure:%s\n", strerror(errno));
        goto cleanup;
    }

    //创建一个新的mosquitto实例
    mosqut = mosquitto_new(mosquitto->client_id, false, (void *)mosquitto);
    if(!mosqut)
    {
        printf("Mosquitto_new failure:%s\n", strerror(errno));
        goto cleanup;
    }
    printf("mosquitto_new successfully!\n");

    //设置回调函数
    mosquitto_connect_callback_set(mosqut, connect_pub_callback);
    printf("0\n");
   if( mosquitto_username_pw_set(mosqut, mosquitto->user, mosquitto->password))
   {
       printf("mosquitto username and password failure:%s\n", strerror(errno));
       goto cleanup;
   }
   printf("1\n");
   while(!g_stop)
   {
       //连接mqtt服务器
	   rv = mosquitto_connect(mosqut, mosquitto->host, mosquitto->port, mosquitto->keepalive);
       if(rv)
       {
           printf("Connect to mqtt server failure:%s\n", strerror(errno));
           sleep(2);
           continue;
       }
       printf("Connect to mqtt server successfully!\n");

       rv = mosquitto_loop_forever(mosqut, -1, 1);
       printf("2\n");
       sleep(10);
       if(rv != MOSQ_ERR_SUCCESS)
       {
           printf("3\n");
           printf("%s\n", strerror(errno));
           goto cleanup;
       }
   }
   printf("mosquitto_pub close\n");
   return 0;

cleanup:
   printf("mosquitto_pub start failure!\n");
   mosquitto_destroy(mosqut);                   //释放mosquitto实例关联的内存
   mosquitto_lib_cleanup();                     //释放库相关的资源
   return 0;
} 

void connect_pub_callback (struct mosquitto *mosqut, void *obj, int rc)
{
	cJSON*          cjson_msg = NULL;
	cJSON*          cjson_properties = NULL;
	char*           str;
	double           temp;
	char           *datetime;
	char           *id = "JMQ";
	int             mid;
	mosquitto_t    *mosq;

	mosq = (mosquitto_t*)obj;

	if((temp = get_temp()) < 0 )
	{
		printf("get temp failuer\n");
	}

	printf("get temp: %.2f摄氏度\n",temp);
	datetime = get_date_time(datetime);
	printf("data is:%s\n",datetime);

	/* 创建一个JSON数据对象(链表头结点) */
	cjson_msg = cJSON_CreateObject();


	/* 添加一个嵌套的JSON数据*/
	cJSON* cjson_params = cJSON_CreateObject();
	cJSON_AddNumberToObject(cjson_params,"CurrentTemperature",temp);
	cJSON_AddItemToObject(cjson_msg,"params",cjson_params);

	str = cJSON_Print(cjson_msg);
	printf("%s\n", str);

	if(rc==0)
	{
		if(mosquitto_publish(mosqut,&mid,mosq->topic,strlen(str)+1,str,0,true)!=MOSQ_ERR_SUCCESS)
		{
			printf("Mosquitto Pub failure: %s\n",strerror(errno));
			return;
		}

		printf("Mosquitto Pub success,pub_topic:%s\n",mosq->topic);
		printf(" rc:%d\n",rc);
	}


	mosquitto_disconnect(mosqut);
	cJSON_Delete(cjson_msg); 
}

char *get_date_time (char *datetime)
{
    char             timechar[1024] = {};
    struct tm       *p;
	time_t           now;
    time(&now); 
	p = localtime(&now);
	sprintf(timechar, "%d-%d-%d %d:%d:%d", p->tm_year+1900, p->tm_mon+1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
    datetime = timechar;
    return datetime;
}

float get_temp ()
{

	char buff[512];
	char distination_file[128];
	char dirpath[200] ="/home/lls/apue/";
	int fd,data_size;
	//打开指定打目录dirpath
	DIR * dir = opendir(dirpath);
	struct dirent *direntp;
	assert(dir != NULL);

	//列出dir里面所以的文件夹和文件	
	while((direntp = readdir(dir)) !=NULL)
	{
		//拿文件名的前俩位和28比较,如果有一个文件的名字前俩个字符是28,则返回0
		if(strncmp(direntp->d_name,"28",2) == 0)
		{
			//将dirpath和ent->d_name写入到fw_file这个字符数组中
			sprintf(distination_file,"%s%s%s",dirpath,direntp->d_name,"/w1_slave");

			fd = open(distination_file, O_RDONLY);
			//使文件偏移量移到文件尾,得到文件内容大小
			data_size = lseek(fd, 0, SEEK_END);

			//然后又使文件偏移量移到文件头,这样才能读文件的内容
			lseek(fd, 0, SEEK_SET);

			if(data_size=0)
				printf("这是个空文件\n");
			read(fd,buff,sizeof(buff));

			//strstr函数返回字符“t=”buff字符串中首次出现的地址
			char *C = strstr(buff,"t=");

			float tem = atof((C+2))/1000;
			printf("读到的数据为:%.2f\n",tem);
			return (tem);
		}
	}
	closedir(dir);
}


.h文件

/********************************************************************************
 *      Copyright:  (C) 2021 li liangshi<1007146932@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  mosquitto_pub.h
 *    Description:  This head file is mosquitto_sub.h 
 *
 *        Version:  1.0.0(2021年08月06日)
 *         Author:  li liangshi <1007146932@qq.com>
 *      ChangeLog:  1, Release initial version on "2021年08月06日 00时14分17秒"
 *                 
 ********************************************************************************/


#ifndef  _MOSQUITTO_PUB_H_
#define  _MOSQUITTO_PUB_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <errno.h>
#include "mosquitto.h"
#include <assert.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include "cJSON.h"
#include "mosquitto.h"


typedef struct mosquitto_s
{
    char        *host;
    int          port;
    char        *topic;
    char        *client_id;
    char        *user;
    char        *password;
    int          keepalive;
    char        pub_message;
}mosquitto_t;

int init_mosquitto_argc (int argc, char **argv, mosquitto_t *mosquitto);
static void print_usage (char *progname);
int mosquitto_pub_start (struct mosquitto *mosqut, mosquitto_t *mosquitto);
void connect_pub_callback (struct mosquitto *mosqut, void *obj, int rc);
char *get_date_time (char *datetime);
float get_temp ();



#endif   /* ----- #ifndef _MOSQUITTO_PUB_H_  ----- */

Makefile文件:


VAR=-l
CC=gcc

all:
	${CC} *.c -o pub ${VAR}mosquitto

run:
	./pub -H "a1xIDqTDkl.iot-as-mqtt.cn-shanghai.aliyuncs.com" -p 1883 -t "/sys/a1xIDqXTDkl/OGlOu7TXgXgItc8UkA9C/thing/event/property/post" -i "hhh|securemode=3,signmethod=hmacsha1,timestamp=60|" -u "OGlOuTXgXgItc8UkA9C&a1xIDXTDkl" -P "1B8BB1F11F7F05D4D4B842D11A1F81DE035FB7" -l 60
	
上一篇:oracle增量备份


下一篇:在Ubuntu上实现mqtt通信