文章目录
libcurl库的制作
1.libcurl简介:
libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。libcurl的官网 、库下载。这种库使用的时候就像使用wiringPi库一样,编写完代码需要链接这个库,所以要先下载这个库。
libcurl的使用(其实和socket编程时一样,都需要一定的步骤):
- 调用curl_global_init()初始化libcurl,(就像初始化套接字)
- 调用curl_easy_init()函数得到 easy interface型指针(这个指针用来各种配置)
- 调用curl_easy_setopt()设置传输选项(通过调用curl_easy_setopt这个函数来对指针进行各种配置,比如:请求的方式)
- 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务
- 调用curl_easy_perform()函数进行访问请求
- 调用curl_easy_cleanup()释放内存
2.下载libcurl库并制作自己的curl库
https://github.com/curl/curl/releases
1.解压 -C表示解压位置
sudo tar -zxvf curl-7.83.1.tar.gz -C /usr/local
2.进入/usr/local/curl-7.83.1
cd /usr/local/curl-7.83.1
3.生成_install
文件
使用./configure configure的目的是和windows一样进行指定文件安装在什么路径上面
–with-ssl :支持https
./configure --prefix=$PWD/_install --with-ssl
4.make make install
make
make install
5.进入_install
目录
cd _install/
6.将include
文件夹和lib
文件夹拷贝出来放在一个目录中
编译时,调用动态库
gcc test.c -o main -I ./include/curl -L ./lib -lcurl
参考:动态库静态库制作
示例:获取网址传回的数据
test.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "curl/curl.h"
//#include "cJSON.h"
// size_t 是一些C/C++标准在stddef.h中定义的,size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数。
//网站传回的数据
size_t MyCallBack(char* p, size_t size, size_t nmemb, void* userdata)
{
char* buf = malloc(size* nmemb);
memcpy(buf,p,size*nmemb);
// cJSON* root = cJSON_Parse(buf);
// if(root == NULL)
// {
// printf("NULL\n");
// return 0;
// }
// char *s = cJSON_Print(root);
printf("%s\n",buf);
free(buf);
}
int main(int argc, char const *argv[])
{
char data[32]="hello";
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl_easy_init();
//设置URL
curl_easy_setopt(curl,CURLOPT_URL,"http://www.baidu.com");
//设置协议头
struct curl_slist *plist = curl_slist_append(NULL,"Content-Type:application/json");
curl_easy_setopt(curl,CURLOPT_HTTPHEADER,plist);
//设置post的回调函数
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,MyCallBack);
//设置传输的数据
curl_easy_setopt(curl,CURLOPT_POST,1);
curl_easy_setopt(curl,CURLOPT_POSTFIELDS,data);
//执行
curl_easy_perform(curl);
//关闭
curl_easy_cleanup(curl);
return 0;
}
编译运行
gcc test.c -I ./include -L ./lib -lcurl
./a.out
3.API说明
相关例子见官网:example.html
4.libcurl库函数介绍:
1.curl_global_init(long flags)
功能:初始化libcurl
这个函数只能用一次。(其实在调用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 curl_easy_init
初始化一个curl会话
CURL *curl_easy_init( );
描述:curl_easy_init用来初始化一个CURL的指针(curl的所有操作就是围绕该指针进行). 相应的在调用结束时要用curl_easy_cleanup函数清理.
注意:一般curl_easy_init意味着一个会话的开始. 它会返回一个easy_handle(CURL*对象), 一般都用在easy系列的函数中。
3 curl_easy_setopt
为curl调用设置一个选项
//设置请求的url【这是唯一要求必须设置的选项,不然咋知道是向谁请求或发送数据】
// Even if you set a crazy value here, curl_easy_setopt will still return CURLE_OK.
// 该url相当于浏览器输入的地址,如果可以带文件,执行后就可以下载文件
curl_easy_setopt(curl_handler, CURLOPT_URL, url);
//设置是否返回请求头
// 设置的值为1,意味要返回请求头;0表示不返回。无其他值
curl_easy_setopt(curl_handler, CURLOPT_HEADER, 1L);
//设置屏蔽其他信号
curl_easy_setopt(curl_handler, CURLOPT_NOSIGNAL, 1L);
//设置下载数据回调函数
// 若置为NULL,则其默认值为fwrite
/*
回调函数原型:
size_t function( void *ptr, size_t size, size_t nmemb, void *userp);
函数将在libcurl接收到数据后被调用。
void *ptr是下载回来的数据.
void *userp是用户指针, 用户通过这个指针传输自己的数据.
CURLOPT_WRITEDATA:设置回调函数中的void *userp指针的来源。
*/
curl_easy_setopt(curl_handler, CURLOPT_WRITEFUNCTION, write_func);
// 如果设置这个值,则必须怼个CURLOPT_WRITEFUNCTION,否则会崩溃
// If you're using libcurl as a win32 DLL, you MUST use a CURLOPT_WRITEFUNCTION if you set this option or you will experience crashes.
curl_easy_setopt(curl_handler, CURLOPT_WRITEDATA, write_data);
//设置是否使用下载进度控制函数
// 为0,表示把下载进度显示在控制台;为1,表示不显示下载进度
curl_easy_setopt(curl_handler, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl_handler, CURLOPT_PROGRESSFUNCTION, prog_func);
curl_easy_setopt(curl_handler, CURLOPT_PROGRESSDATA, pdata);
// 下载进度回调函数与下载数据的回调函数原型相同,data也相同。
//设置请求头
struct curl_list *header_list = NULL;
header_list = curl_slist_append(header_list, headers);
curl_easy_setopt(curl_handler, CURLOPT_HTTPHEADER, header_list);
curl_slist_free_all(header_list);
//其他选项
CURLOPT_HEADERFUNCTION
// 只取HTTP头部数据, 处理与下载数据回调的处理相同.
CURLOPT_HEADERDATA
// 超时时间
CURLOPT_TIMEOUT
// 连接等待时间.
CURLOPT_CONNECTIONTIMEOUT
// 设置支持302重定向
CURLOPT_FOLLOWLOCATION
// 断点续传, 指定传输分片, 格式:"0-200"
CURLOPT_RANGE
描述:该函数可以设置访问url的属性,具体设置可看libcurl官网介绍:https://curl.haxx.se/libcurl/c/
注:如果设置Post方式发送数据,则需要设置 CURLOPT_POSTFIELDS和CURLOPT_POSTFIELDSIZE
PS:若需要复制该设置的属性,调用curl_easy_duphandle.若需要清空之前设置的属性,可以调用curl_easy_reset
4.curl_easy_perform执行一个curl会话
CURLcode curl_easy_perform(CURL *handler);
描述:执行当次请求创建的句柄,在curl_easy_setopt完成后调用,执行我们设置的option。返回值可以从官网中获取意义:https://curl.haxx.se/libcurl/c/libcurl-errors.html
5.curl_easy_cleanup
void curl_easy_cleanup(CURL *handler);//关闭一个curl会话,用来结束一个会话.与curl_easy_init配合着用.
6. curl_global_cleanup
void curl_global_cleanup();
libcurl是线程安全的,但curl_global_cleanup是不能保证线程安全的。因此需在主线程调用该函数,而不是在每个线程中调用。
参考:
https://www.cnblogs.com/xietianjiao/p/13260021.html
https://blog.csdn.net/byxdaz/article/details/81869881