项目之用ARM串口关联巴法云进行推送或者订阅

目录

一、LibCurl基本编程框架

二、一些基本的函数

1.CURLcode curl_global_init(long flags);

2 void curl_global_cleanup(void);

3 char *curl_version( );

4 CURL *curl_easy_init( );

5 void curl_easy_cleanup(CURL *handle);

6 CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);

7 CURLcode curl_easy_perform(CURL *handle);


一、LibCurl基本编程框架


libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。想要知道更多关于libcurl的介绍,可以到官网 curl上去了解,在这里不再详述。

win32版的libcurl下载地址:http://curl.freeby.pctools.cl/download/libcurl-7.18.0-win32-msvc.zip

在基于LibCurl的程序里,主要采用callback function (回调函数)的形式完成传输任务,用户在启动传输前设置好各类参数和回调函数,当满足条件时libcurl将调用用户的回调函数实现特定功能。

下面是利用libcurl完成传输任务的流程:

1.       调用curl_global_init()初始化libcurl
2.       调用curl_easy_init()函数得到 easy interface型指针
3.       调用curl_easy_setopt()设置传输选项
4.       根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务
5.       调用curl_easy_perform()函数完成传输任务
6.       调用curl_easy_cleanup()释放内存

在整过过程中设置curl_easy_setopt()参数是最关键的,几乎所有的libcurl程序都要使用它。

二、一些基本的函数


1.CURLcode curl_global_init(long flags);


描述:
这个函数只能用一次。(其实在调用curl_global_cleanup 函数后仍然可再用)
如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动调用,所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。

注意:虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。
参数:flags
CURL_GLOBAL_ALL                      //初始化所有的可能的调用。
CURL_GLOBAL_SSL                      //初始化支持 安全套接字层。
CURL_GLOBAL_WIN32            //初始化win32套接字库。
CURL_GLOBAL_NOTHING         //没有额外的初始化。


2 void curl_global_cleanup(void);


描述:在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。

注意:虽然libcurl是线程安全的,但curl_global_cleanup是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。


3 char *curl_version( );


描述: 打印当前libcurl库的版本。


4 CURL *curl_easy_init( );


描述:
curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样). 相应的在调用结束时要用curl_easy_cleanup函数清理.
一般curl_easy_init意味着一个会话的开始. 它会返回一个easy_handle(CURL*对象), 一般都用在easy系列的函数中.


5 void curl_easy_cleanup(CURL *handle);


描述:
这个调用用来结束一个会话.与curl_easy_init配合着用. 
参数:
CURL类型的指针.


6 CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);


描述: 这个函数最重要了.几乎所有的curl 程序都要频繁的使用它.它告诉curl库.程序将有如何的行为. 比如要查看一个网页的html代码等.(这个函数有些像ioctl函数)参数:
1 CURL类型的指针
2 各种CURLoption类型的选项.(都在curl.h库里有定义,man 也可以查看到)
3 parameter 这个参数 既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量.它用什么这取决于第二个参数.
CURLoption 这个参数的取值很多.具体的可以查看man手册.


7 CURLcode curl_easy_perform(CURL *handle);

描述:这个函数在初始化CURL类型的指针 以及curl_easy_setopt完成后调用. 就像字面的意思所说perform就像是个舞台.让我们设置的
option 运作起来.参数:
CURL类型的指针.

转载于:C++ 用libcurl库进行http通讯网络编程 - 绿色冰点 - 博客园 (cnblogs.com)

/*===============================================
 *   文件名称:weather.c
 *   创 建 者:     
 *   创建日期:2022年09月15日
 *   描    述:
 ================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "cJSON.h"
#include <sys/types.h>
#include <unistd.h>
//串口协议结构体相关头文件
#include <termios.h>
#include <sys/stat.h>
#include <fcntl.h>
char uid[50]="dc656d5a1d4a4398bbfde41436a7226e";
char topic[20]="env";
char type[2] = "1";
// char msg[24];

//用 get 方法推送主题
void pushGetTopic(char *msg);
//用 post 方法推送主题
void pushPostTopic(char *msg);
//只能用 get 方法订阅主题
char getTopic(char *msg);
//声明回调函数,用于接受网页回复的数据
size_t myRecv(void *buffer, size_t size, size_t nmemb, void *userp);

void pushGetTopic(char *msg)
{
        char url[256]={0};
        sprintf(url,"https://apis.bemfa.com/va/getpushmsg?uid=%s&topic=%s&type=%s&msg=%s",uid,topic,type,msg);

        //全局初始化 curl库,void型,只调用一次
        curl_global_init(CURL_GLOBAL_ALL);
        //初始化 easy interface相关接口,得到 easy_handle指针
        CURL *curl = curl_easy_init();
        if(curl != NULL){
            //设置请求的url网址
            curl_easy_setopt(curl, CURLOPT_URL,url);
            //不验证数字信息,1L为验证数字信息
            curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L);//CURLOPT_SSL_VERIFYPEER:验证SSL证书  verifypeer
            //设置请求的方式
            curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"GET");//CURLOPT_CUSTOMREQUEST:自定义请求方法  customrequest
            //curl_easy_setopt(curl,CURLOPT_POST,0);

	        //定义结构体指针
            struct curl_slist *headers = NULL;
            //将头部信息追加到指针中
            headers=curl_slist_append(headers,"Content-Type:application/x-www-form-urlencoded");
            curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);//CURLOPT_HTTPHEADER:自定义 HTTP 头
            //设置注册回调函数
            curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,myRecv);//CURLOPT_WRITEFUNCTION:用于写入数据的回调 writefunction
            //执行请求
            int errno = curl_easy_perform(curl);
            if(errno != CURLE_OK){
                printf("执行错误:%d\n",errno);
            }
            //释放url指针
            curl_easy_cleanup(curl);
            //释放请求头
            curl_slist_free_all(headers);
        }
    //7、清除curl库的相关资源
    curl_global_cleanup();
}
void pushPostTopic(char *msg)
{ 
        char url[256]={0};
        sprintf(url,"https://apis.bemfa.com/va/postmsg?uid=%s&topic=%s&type=%s&msg=%s",uid,topic,type,msg);

        curl_global_init(CURL_GLOBAL_ALL);
        CURL *curl = curl_easy_init();
        if(curl != NULL){
            curl_easy_setopt(curl, CURLOPT_URL,url);
            //不验证数字信息
            curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L);
            //设在请求方式为 post
            curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"POST");
//            curl_easy_setopt(curl,CURLOPT_POST,1);
	    //定义结构体指针
            struct curl_slist *headers = NULL;
            //将头部信息追加到指针中
            headers=curl_slist_append(headers,"Content-Type:application/x-www-form-urlencoded");
            curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
            //设置注册回调函数
            curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,myRecv);
            //执行请求
            int errno = curl_easy_perform(curl);
            if(errno != CURLE_OK){
                printf("执行错误: %d :%s\n",errno,curl_easy_strerror(errno));
            }
            //释放url指针
            curl_easy_cleanup(curl);
            //释放请求头
            curl_slist_free_all(headers);
        }
    //7、清除curl库的相关资源
    curl_global_cleanup();
} 
char getTopic(char *msg)
{
 	char url[256]={0};
    sprintf(url,"https://apis.bemfa.com/va/getmsg?uid=%s&topic=%s&type=%s",uid,topic,type);

    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
    if(curl != NULL){
        curl_easy_setopt(curl, CURLOPT_URL,url);
        //不验证数字信息
        curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L);
        // curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,"GET");
        //    curl_easy_setopt(curl,CURLOPT_POST,1);

        // //定义结构体指针
        // struct curl_slist *headers = NULL;
        // //将头部信息追加到指针中
        // headers=curl_slist_append(headers,"Content-Type:application/x-www-form-urlencoded");
        // curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
        //设置注册回调函数
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,myRecv);
        //执行请求
        int errno = curl_easy_perform(curl);
        if(errno != CURLE_OK){
            printf("执行错误: %d :%s\n",errno,curl_easy_strerror(errno));
        }
        //释放url指针
        curl_easy_cleanup(curl);
        //释放请求头
        // curl_slist_free_all(headers);
    }
    //7、清除curl库的相关资源
    curl_global_cleanup();
}
/*
 * 如果回复的数据是json格式∶
 * 1、先使用c]S0N *c]son_Parse( char *buffer);
 *      函数转换成cJ5ON对象。
 * 2、可以使用char * c]SON_Print(cJSON *node) ;
 *      函数将json对象类型数据转换成char *类型的数据。
 * 3、可以使用cJSON *cSON_Get0bjectItem(cJSON *node,char *key);
 *      函数,取某个key的 value值。
 * 4、可以使用if( node->type =- c]SON_Array)来进行判断 value值是否是一个json数组
 * 5、通过使用int cJSON_GetArraysize( cJ50N *node) ;
 *      函数,可以获得node这个json数组中的元素个数。
 * 6、可以通过cJSON *CJSON_GetArrayItem( cJSON *node,int i);
 *      函数,可以获得node这个json数组中下标为i的元素。
 * 7、在cJSON结构体中,提供 valuestring\ valuedouble等结构体成员
 *      来表示key的 value值的字符串类型、符点类型数据。
 */
size_t myRecv(void *buffer, size_t size, size_t nmemb, void *userp)
{
    printf("---%s\n",(char *)buffer);
#if 0
    printf("-----------------size: %ld n: %ld-----------------\n %s\n",size,nmemb,(char*)buffer);

    //创建cJSON对象,将buffer转换成cJSON类型
    cJSON *root = cJSON_Parse((char *)buffer);
    //cJSON_Print():打印 cJSON 对象的内容
    printf("root:%s\n",cJSON_Print(root));

    //cJSON_GetObjectItem():取出某个 Key的 Value值
    root = cJSON_GetObjectItem(root,"weatherinfo");
    if(NULL==root){
        printf("没有该数据\n");
        return size*nmemb;
    }
    printf("%s\n",cJSON_Print(root));
    if( root->type == cJSON_Array ){
        printf("value值是一个json数组\n");
    }
    if( root->type== cJSON_Object ){
        printf("weatherinfo 的 value 值是一个JSON对象\n");
        //cJSON *node = NULL;
        cJSON *node = cJSON_GetObjectItem(root,"temp");
        if(NULL==node){
            printf("没有temp数据\n");
            return size*nmemb;
        }
        //node->valuestring : 获取node中的数据的字符串形式,valuestring是一个结构体成员
        printf("temp:%s\n",node->valuestring);
    }
#endif
    //执行完成,必须返回 size*nmemb
    return size*nmemb;
}
int main(int argc, char *argv[])
{
    //打开串口设备,必须确保这里的串口能够使用
    int fd = open("/dev/ttyS0",O_RDWR);
    if(fd<0){
        perror("open");
        return -1;
    }
    //设置串口协议
    struct termios options;
    tcgetattr(fd, &options);
    options.c_cflag |= (CLOCAL | CREAD);//忽略调制解调器线路状态    使用接收器
    options.c_cflag &= ~CSIZE;  //字符长度,取值范围为CS5、CS6、CS7或CS8
    options.c_cflag &= ~CRTSCTS;//不使用RTS/CTS流控制
    options.c_cflag |= CS8;//设置数据位
    options.c_cflag &=~ CSTOPB;//不设置两个停止位,设置为1个停止位
    options.c_iflag |= IGNPAR;//忽略奇偶校验错误
    options.c_iflag &=~(ICRNL|IXON);//将输入的回车转化成换行(如果IGNCR未设置的情况下)     允许输入时对XON/XOFF流进行控制
    options.c_oflag =0;
    options.c_lflag =0;

    cfsetispeed(&options,B115200);
    cfsetospeed(&options,B115200);//two is 波特率
    tcsetattr(fd,TCSANOW,&options);//将串口协议设置到fd中立即生效

    unsigned char buf[36] = {0};
    while(1){
        int count = 0;
        while(count<36){
            int ret=read(fd,buf+count,36-count);
            if(ret<0)
                break;
            count += ret;
        }
    
        for(int i=0;i<36;i++)
            printf("%2d ",buf[i]);
        printf("\n");
        char msg[8]={0};
        int t = buf[4] + (int)buf[5];
        sprintf(msg,"t:%d",t);
        printf("%s\n",msg);
        sleep(1);

        // pushGetTopic(msg);
        pushPostTopic(msg);
        printf("==================================\n");
        getTopic(msg);

    }
    return 0;
}

参考文档:

Linux下的libcurl库的使用(学习总结)_程序猿-小土豆的博客-CSDN博客_libcurl linux

libcurl库详解:
https://blog.csdn.net/hhltaishuai/article/details/115593271
C语言libcurl的安装以及接口的使用方法:
https://blog.csdn.net/weixin_48503637/article/details/122582089
libcurl库下载:
sudo apt-get install libcurl4-openssl-dev
liunx快速查找文件:
https://blog.csdn.net/xxmonstor/article/details/80507769
头文件目录:/usr/include/x86_64-linux-gnu/curl/curl.h

串口编程:https://www.freesion.com/article/6013164167/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值