• 项目之用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)

    1. /*===============================================
    2. * 文件名称:weather.c
    3. * 创 建 者:
    4. * 创建日期:2022年09月15日
    5. * 描 述:
    6. ================================================*/
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include "cJSON.h"
    12. #include
    13. #include
    14. //串口协议结构体相关头文件
    15. #include
    16. #include
    17. #include
    18. char uid[50]="dc656d5a1d4a4398bbfde41436a7226e";
    19. char topic[20]="env";
    20. char type[2] = "1";
    21. // char msg[24];
    22. //用 get 方法推送主题
    23. void pushGetTopic(char *msg);
    24. //用 post 方法推送主题
    25. void pushPostTopic(char *msg);
    26. //只能用 get 方法订阅主题
    27. char getTopic(char *msg);
    28. //声明回调函数,用于接受网页回复的数据
    29. size_t myRecv(void *buffer, size_t size, size_t nmemb, void *userp);
    30. void pushGetTopic(char *msg)
    31. {
    32. char url[256]={0};
    33. sprintf(url,"https://apis.bemfa.com/va/getpushmsg?uid=%s&topic=%s&type=%s&msg=%s",uid,topic,type,msg);
    34. //全局初始化 curl库,void型,只调用一次
    35. curl_global_init(CURL_GLOBAL_ALL);
    36. //初始化 easy interface相关接口,得到 easy_handle指针
    37. CURL *curl = curl_easy_init();
    38. if(curl != NULL){
    39. //设置请求的url网址
    40. curl_easy_setopt(curl, CURLOPT_URL,url);
    41. //不验证数字信息,1L为验证数字信息
    42. curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L);//CURLOPT_SSL_VERIFYPEER:验证SSL证书 verifypeer
    43. //设置请求的方式
    44. curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"GET");//CURLOPT_CUSTOMREQUEST:自定义请求方法 customrequest
    45. //curl_easy_setopt(curl,CURLOPT_POST,0);
    46. //定义结构体指针
    47. struct curl_slist *headers = NULL;
    48. //将头部信息追加到指针中
    49. headers=curl_slist_append(headers,"Content-Type:application/x-www-form-urlencoded");
    50. curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);//CURLOPT_HTTPHEADER:自定义 HTTP 头
    51. //设置注册回调函数
    52. curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,myRecv);//CURLOPT_WRITEFUNCTION:用于写入数据的回调 writefunction
    53. //执行请求
    54. int errno = curl_easy_perform(curl);
    55. if(errno != CURLE_OK){
    56. printf("执行错误:%d\n",errno);
    57. }
    58. //释放url指针
    59. curl_easy_cleanup(curl);
    60. //释放请求头
    61. curl_slist_free_all(headers);
    62. }
    63. //7、清除curl库的相关资源
    64. curl_global_cleanup();
    65. }
    66. void pushPostTopic(char *msg)
    67. {
    68. char url[256]={0};
    69. sprintf(url,"https://apis.bemfa.com/va/postmsg?uid=%s&topic=%s&type=%s&msg=%s",uid,topic,type,msg);
    70. curl_global_init(CURL_GLOBAL_ALL);
    71. CURL *curl = curl_easy_init();
    72. if(curl != NULL){
    73. curl_easy_setopt(curl, CURLOPT_URL,url);
    74. //不验证数字信息
    75. curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L);
    76. //设在请求方式为 post
    77. curl_easy_setopt(curl,CURLOPT_CUSTOMREQUEST,"POST");
    78. // curl_easy_setopt(curl,CURLOPT_POST,1);
    79. //定义结构体指针
    80. struct curl_slist *headers = NULL;
    81. //将头部信息追加到指针中
    82. headers=curl_slist_append(headers,"Content-Type:application/x-www-form-urlencoded");
    83. curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
    84. //设置注册回调函数
    85. curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,myRecv);
    86. //执行请求
    87. int errno = curl_easy_perform(curl);
    88. if(errno != CURLE_OK){
    89. printf("执行错误: %d :%s\n",errno,curl_easy_strerror(errno));
    90. }
    91. //释放url指针
    92. curl_easy_cleanup(curl);
    93. //释放请求头
    94. curl_slist_free_all(headers);
    95. }
    96. //7、清除curl库的相关资源
    97. curl_global_cleanup();
    98. }
    99. char getTopic(char *msg)
    100. {
    101. char url[256]={0};
    102. sprintf(url,"https://apis.bemfa.com/va/getmsg?uid=%s&topic=%s&type=%s",uid,topic,type);
    103. curl_global_init(CURL_GLOBAL_ALL);
    104. CURL *curl = curl_easy_init();
    105. if(curl != NULL){
    106. curl_easy_setopt(curl, CURLOPT_URL,url);
    107. //不验证数字信息
    108. curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,0L);
    109. // curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,"GET");
    110. // curl_easy_setopt(curl,CURLOPT_POST,1);
    111. // //定义结构体指针
    112. // struct curl_slist *headers = NULL;
    113. // //将头部信息追加到指针中
    114. // headers=curl_slist_append(headers,"Content-Type:application/x-www-form-urlencoded");
    115. // curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
    116. //设置注册回调函数
    117. curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,myRecv);
    118. //执行请求
    119. int errno = curl_easy_perform(curl);
    120. if(errno != CURLE_OK){
    121. printf("执行错误: %d :%s\n",errno,curl_easy_strerror(errno));
    122. }
    123. //释放url指针
    124. curl_easy_cleanup(curl);
    125. //释放请求头
    126. // curl_slist_free_all(headers);
    127. }
    128. //7、清除curl库的相关资源
    129. curl_global_cleanup();
    130. }
    131. /*
    132. * 如果回复的数据是json格式∶
    133. * 1、先使用c]S0N *c]son_Parse( char *buffer);
    134. * 函数转换成cJ5ON对象。
    135. * 2、可以使用char * c]SON_Print(cJSON *node) ;
    136. * 函数将json对象类型数据转换成char *类型的数据。
    137. * 3、可以使用cJSON *cSON_Get0bjectItem(cJSON *node,char *key);
    138. * 函数,取某个key的 value值。
    139. * 4、可以使用if( node->type =- c]SON_Array)来进行判断 value值是否是一个json数组
    140. * 5、通过使用int cJSON_GetArraysize( cJ50N *node) ;
    141. * 函数,可以获得node这个json数组中的元素个数。
    142. * 6、可以通过cJSON *CJSON_GetArrayItem( cJSON *node,int i);
    143. * 函数,可以获得node这个json数组中下标为i的元素。
    144. * 7、在cJSON结构体中,提供 valuestring\ valuedouble等结构体成员
    145. * 来表示key的 value值的字符串类型、符点类型数据。
    146. */
    147. size_t myRecv(void *buffer, size_t size, size_t nmemb, void *userp)
    148. {
    149. printf("---%s\n",(char *)buffer);
    150. #if 0
    151. printf("-----------------size: %ld n: %ld-----------------\n %s\n",size,nmemb,(char*)buffer);
    152. //创建cJSON对象,将buffer转换成cJSON类型
    153. cJSON *root = cJSON_Parse((char *)buffer);
    154. //cJSON_Print():打印 cJSON 对象的内容
    155. printf("root:%s\n",cJSON_Print(root));
    156. //cJSON_GetObjectItem():取出某个 Key的 Value值
    157. root = cJSON_GetObjectItem(root,"weatherinfo");
    158. if(NULL==root){
    159. printf("没有该数据\n");
    160. return size*nmemb;
    161. }
    162. printf("%s\n",cJSON_Print(root));
    163. if( root->type == cJSON_Array ){
    164. printf("value值是一个json数组\n");
    165. }
    166. if( root->type== cJSON_Object ){
    167. printf("weatherinfo 的 value 值是一个JSON对象\n");
    168. //cJSON *node = NULL;
    169. cJSON *node = cJSON_GetObjectItem(root,"temp");
    170. if(NULL==node){
    171. printf("没有temp数据\n");
    172. return size*nmemb;
    173. }
    174. //node->valuestring : 获取node中的数据的字符串形式,valuestring是一个结构体成员
    175. printf("temp:%s\n",node->valuestring);
    176. }
    177. #endif
    178. //执行完成,必须返回 size*nmemb
    179. return size*nmemb;
    180. }
    181. int main(int argc, char *argv[])
    182. {
    183. //打开串口设备,必须确保这里的串口能够使用
    184. int fd = open("/dev/ttyS0",O_RDWR);
    185. if(fd<0){
    186. perror("open");
    187. return -1;
    188. }
    189. //设置串口协议
    190. struct termios options;
    191. tcgetattr(fd, &options);
    192. options.c_cflag |= (CLOCAL | CREAD);//忽略调制解调器线路状态 使用接收器
    193. options.c_cflag &= ~CSIZE; //字符长度,取值范围为CS5、CS6、CS7或CS8
    194. options.c_cflag &= ~CRTSCTS;//不使用RTS/CTS流控制
    195. options.c_cflag |= CS8;//设置数据位
    196. options.c_cflag &=~ CSTOPB;//不设置两个停止位,设置为1个停止位
    197. options.c_iflag |= IGNPAR;//忽略奇偶校验错误
    198. options.c_iflag &=~(ICRNL|IXON);//将输入的回车转化成换行(如果IGNCR未设置的情况下) 允许输入时对XON/XOFF流进行控制
    199. options.c_oflag =0;
    200. options.c_lflag =0;
    201. cfsetispeed(&options,B115200);
    202. cfsetospeed(&options,B115200);//two is 波特率
    203. tcsetattr(fd,TCSANOW,&options);//将串口协议设置到fd中立即生效
    204. unsigned char buf[36] = {0};
    205. while(1){
    206. int count = 0;
    207. while(count<36){
    208. int ret=read(fd,buf+count,36-count);
    209. if(ret<0)
    210. break;
    211. count += ret;
    212. }
    213. for(int i=0;i<36;i++)
    214. printf("%2d ",buf[i]);
    215. printf("\n");
    216. char msg[8]={0};
    217. int t = buf[4] + (int)buf[5];
    218. sprintf(msg,"t:%d",t);
    219. printf("%s\n",msg);
    220. sleep(1);
    221. // pushGetTopic(msg);
    222. pushPostTopic(msg);
    223. printf("==================================\n");
    224. getTopic(msg);
    225. }
    226. return 0;
    227. }

    参考文档:

    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/

  • 相关阅读:
    testng-xslt使用详细教程
    ERROR in static/js/xxx.js from UglifyJs Unexpected token name «currentVersion»
    Linux:I/O 5种模型
    【python基础】用户输入和while循环详解
    Excel基于分隔符拆分列
    你的Web3域名 价值究竟何在?
    [Qt]窗口
    【SwitchyOmega】SwitchyOmega 安装及使用
    WIFI版本云音响设置教程腾讯云平台版本
    Oracle中的循环
  • 原文地址:https://blog.csdn.net/hold_the_key/article/details/126907720