1.下载并解压
下载到的压缩包为curl-7.59.0.tar.gz使用命令:
$wget http://curl.haxx.se/download/curl-7.59.0.tar.gz
解压:
$tar -zxvf curl-7.59.0.tar.gz
2.进入解压出的目录curl-7.59.0.
$cd curl-7.59.0
3.建立编译夹
$mkdir install
4.配置参数
./configure --host=arm-fsl-linux-gnueabi prefix=`pwd`/install CC=arm-fsl-linux-gnueabi-gcc CXX=arm-fsl-linux-gnueabi-g++
【注意】
–host=arm-fsl-linux-gnueabi表示该软件编译完成后在arm平台上运行
–prefix后面为软件安装目录 5.编译
$make
$make install
6.查看
$ls install/
libcurl头文件在install/include/curl目录
# ls install/include/curl
交叉编译后的动态库文件在lib目录
$ls install/lib
7.移植
将lib文件下的移植到开发板的/usr/lib。
8.测试 Test.c#include #include #include
const char data[]="this is what we post to the silly web server";
struct WriteThis
{
const char *readptr;
long sizeleft;
};
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct WriteThis *pooh = (struct WriteThis *)userp;
if(size*nmemb < 1)
return0;
if(pooh->sizeleft)
{
*(char *)ptr = pooh->readptr[0]; /* copy one single byte */
pooh->readptr++; /* advance pointer */
pooh->sizeleft--; /* less data left */ return1; /* we return1 byte at a time! */
}
return0; /* no more data left to deliver */
}
int main(void)
{
CURL *curl;
CURLcode res;
struct WriteThis pooh;
pooh.readptr = data;
pooh.sizeleft = (long)strlen(data);
/* In windows, this will init the winsock stuff */
res = curl_global_init(CURL_GLOBAL_DEFAULT);
/* Check for errors */
if(res != CURLE_OK)
{
fprintf(stderr, "curl_global_init() failed: %s
",
curl_easy_strerror(res));
return1;
}
/* get a curl handle */
curl = curl_easy_init();
if(curl)
{
/* First setthe URL thatisaboutto receive our POST. */
curl_easy_setopt(curl, CURLOPT_URL, "http://47.106.72.113/");
/* Now specify we want to POST data */
curl_easy_setopt(curl, CURLOPT_POST, 1L);
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* pointer to pass to our read function */
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
/* get verbose debug output please */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/*
If you use POST to a HTTP 1.1 server, you can send data without knowing
the size before starting the POST if you use chunked encoding. You
enable this by adding a header like "Transfer-Encoding: chunked"with
CURLOPT_HTTPHEADER. With HTTP 1.0orwithout chunked transfer, you must
specify the size inthe request.
*/
#ifdef USE_CHUNKED
{
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
/* use curl_slist_free_all() afterthe *perform() call to free this
list again */
}
#else
/* Set the expected POST size. If you want to POST large amounts of data,
consider CURLOPT_POSTFIELDSIZE_LARGE */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pooh.sizeleft);
#endif #ifdef DISABLE_EXPECT
/*
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
header. You can disable this header with CURLOPT_HTTPHEADER as usual.
NOTE: if you want chunked transfer too, you need to combine these two
since you can only set one listof headers with CURLOPT_HTTPHEADER. */
/* A less good option would be to enforce HTTP 1.0, butthat might also
have other implications. */
{
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Expect:");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
/* use curl_slist_free_all() afterthe *perform() call to free this
list again */
}
#endif
/* Perform the request, res will getthereturn code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s
",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return0;
}
执行命令:
$arm-fsl-linux-gnueabi-gcc -I/home/farsight/curl-7.59.0/install/include -L/home/farsight/curl-7.59.0/install/lib -o test test.c -lcurl
将可执行文件test拷贝到开发板,执行程序。可以见到如下信息。
* Trying 47.106.72.113...
* TCP_NODELAY set
* Connected to 47.106.72.113 (47.106.72.113) port 80 (#0)
> POST / HTTP/1.1
Host: 47.106.72.113
Accept: */*
Content-Length: 44
Content-Type: application/x-www-form-urlencoded
* We are completely uploaded and fine
< HTTP/1.1405NotAllowed
< Server:nginx/1.8.1
< Date:Mon, 25Jun201805:45:38GMT
< Content-Type:text/html
< Content-Length:172
< Connection:keep-alive
<
<html><head><title>405 Not Allowedtitle>head><bodybgcolor="white"><center><h1>405 Not Allowedh1>center><hr><center>nginx/1.8.1center>body>html>
* Connection #0 to host 47.106.72.113 left intact
libcurl测试实例集:https://curl.haxx.se/libcurl/c/example.html
关于libcurl实例参看以上网址。
8.1.2 Curl使用步骤
1.全局初始化CURLcode curl_global_init(long flags);
flags:
CURL_GLOBAL_ALL //初始化所有内部的模块
CURL_GLOBAL_SSL //初始化支持安全套接字
CURL_GLOBAL_WIN32 //初始化win32套接字库
CURL_GLOBAL_NOTHING //不初始化任何额外模块
CURL_GLOBAL_DEFAULT //与CURL_GLOBAL_ALL相同
该函数必须再所有其他libcurl函数调用前被调用,从而构建整个libcurl函数运行所需的环境,多次调用是幂等的。flags参数能够使用”或”操作符进行多个选项的拼接。一般情况使用CURL_GLOBAL_ALL是最好的选择。
该函数不是线程安全的,不能在程序的其他线程中调用,只能应用程序开始时,进行全局初始化调用。虽然不调用这个函数,使用curl_easy_init也会自行调用该函数,但在多线程处理时,可能出现多次调用的情况,应避免。 2.创建当次请求句柄
每次请求都需要创建一个句柄,所有操作围绕以此句柄进行:
CURL *curl_handler = curl_easy_init();3.设置属性
libcurl针对所有协议,统一使用一个简单的函数curl_easy_setopt进行设置,这大大简化了使用,不过需要参考不同协议设置不同的属性: https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
这里以http发送GET请求为例设置如下:
//设置请求的urlcurl_easy_setopt(curl_handler, CURLOPT_URL, url);
//设置是否返回请求头curl_easy_setopt(curl_handler, CURLOPT_HEADER, 1L);
//设置屏蔽其他信号curl_easy_setopt(curl_handler, CURLOPT_NOSIGNAL, 1L);
//设置下载数据回调函数curl_easy_setopt(curl_handler, CURLOPT_WRITEFUNCTION, write_func);
curl_easy_setopt(curl_handler, CURLOPT_WRITEDATA, write_data);
回调函数原型:
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_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;
for (int i = 0; i < headers.size(); ++i) {
header_list = curl_slist_append(header_list, headers[i].c_str());
}
curl_easy_setopt(curl_handler, CURLOPT_HTTPHEADER, header_list);
curl_slist_free_all(header_list);
//其他选项
CURLOPT_HEADERFUNCTION
CURLOPT_HEADERDATA
只取HTTP头部数据, 处理与下载数据回调的处理相同.
CURLOPT_TIMEOUT
超时时间.
CURLOPT_CONNECTIONTIMEOUT
连接等待时间.
CURLOPT_FOLLOWLOCATION
设置支持302重定向
CURLOPT_RANGE
断点续传, 指定传输分片, 格式:”0-200”
其中,针对http协议,不同请求有特定的属性需要设置,下面依次列举:
- HEAD:需要设置CURLOPT_NOBODY为true
- DELETE:需要设置CURLOPT_CUSTOMREQUEST为”DELETE”
- PUT:需要设置CURLOPT_UPLOAD为true,同时设置CURLOPT_READFUNCTION、CURLOPT_READDATA、CURLOPT_INFILESIZE_LARGE
- POST:需要设置CURLOPT_POST为true,设置CURLOPT_POSTFIELDS、CURLOPT_POSTFIELDSIZE
4.执行CURLcode curl_easy_perform(CURL *handler);
该函数执行当次请求创建的句柄,返回值有非常详细的定义libcurl库返回状态码解释与速查。 5.销毁当次请求句柄void curl_easy_cleanup(CURL *handler);
该函数销毁当次请求创建的句柄。 6.全局析构void curl_global_cleanup();
该函数销毁全局执行环境。
其他接口
libcurl除了上述常用接口外,提供了其他接口可以进行更为方便和精确的控制。
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );
//支持的CURLINFO类型见此:https://curl.haxx.se/libcurl/c/curl_easy_getinfo.htmlcurl_version() returns apointer to the libcurl version string
curl_getdate() converts a date string to time_t
curl_formadd() build multipart form-data posts
curl_formfree() free a previously built form POST
curl_slist_append() builds a linked list
curl_slist_free_all() frees a whole curl_slist as made with curl_slist_append()curl_easy_escape() URL encodes a string
curl_easy_unescape() URL decodes a string
libcurl官方教程:https://curl.haxx.se/libcurl/c/libcurl-tutorial.html