1 摘要

1.1 平台


运行平台:君正x2000

libcurl版本:7.68.0,通过buildroot编译生成。

编译器:mips-linux-gnu-gcc (gcc version 7.2.0 (Ingenic r4.0.0-gcc720 2018.02-28))

编译主机:ubuntu 18.04


 1.2 功能


http通信(1)

1.1最少的代码实现http访问百度,这个示例将通过get方法访问百度,并将百度返回的结果存入data.html文件中。

http通信(2)

2.1 增加获取libcurl库信息

2.2 增加打印打印http响应head数据

2.3 增加使能版本库调试功能

http通信(3)

3.1 在http请求中增加头部的字段

http通信(4)

4.1 获取libcurl执行过程信息


 2 信息名称:CURLINFO_TOTAL_TIME 


获取上一次的总传输时间


2.1 原型


#include <curl/curl.h>

CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_TOTAL_TIME, double *timep);


2.2 描述


传递一个指向double的指针来接收前一次传输的总时间(以秒为单位),包括名称解析、TCP连接等,double表示以秒为单位的时间。

当执行重定向时,每个请求的时间被加在一起。


2.3 示例代码

curl = curl_easy_init();
if(curl) {
double total;
curl_easy_setopt(curl, CURLOPT_URL, url);
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total);
if(CURLE_OK == res) {
printf("Time: %.1f", total);
}
}
/* always cleanup */
curl_easy_cleanup(curl);
}

3 信息名称:CURLINFO_CONNECT_TIME


获取连接过程的时间


3.1 原型


#include <curl/curl.h>

CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_CONNECT_TIME, double *timep);


3.2 描述


传递一个指向double的指针来接收从开始到远程主机(或代理)连接完成的总时间(以秒为单位)。

当执行重定向时,每个请求的时间被加在一起。


3.3 示例代码

curl = curl_easy_init();
if(curl) {
double connect;
curl_easy_setopt(curl, CURLOPT_URL, url);
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
res = curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &connect);
if(CURLE_OK == res) {
printf("Time: %.1f", connect);
}
}
/* always cleanup */
curl_easy_cleanup(curl);
}

4 信息名称:CURLINFO_SIZE_DOWNLOAD 


获取下载的字节数。


4.1 原型


#include <curl/curl.h>

CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_SIZE_DOWNLOAD, double *dlp);


4.2 描述


传递一个指向double的指针来接收下载的字节总数。这个数据只针对最后一次传输,每一次传输都会重新计算这个数。这是计算实际有效载荷数据,通常也被称为body。所有元数据和头部数据将不被计算在内。


4.3 示例

CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");

/* Perform the request */
res = curl_easy_perform(curl);

if(!res) {
/* check the size */
double dl;
res = curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &dl);
if(!res) {
printf("Downloaded %.0f bytes\n", cl);
}
}

5 代码实现

Makefile

LIBS=-L../../../buildroot/output/target/usr/lib -lpthread -lz -lcurl -lcrypto -lssl -lcjson
CC_FLAG=-Wall -I../../../buildroot/output/staging/usr/include
SRC=curl_test.c
CC=mips-linux-gnu-gcc


test : $(SRC)
$(CC) $< $(LIBS) $(CC_FLAG) -O2 -o $@
cp -v $@ ~/nfs

.PHONY : clean

clean :
rm -rf test

curl_test.c

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

static void baidu_get_test(void);
static void print_version_info(void);

int main()
{
CURLcode code;
code = curl_global_init(CURL_GLOBAL_ALL);

if(CURLE_OK != code) {
printf("curl init Err\n");
return -1;
}

/*
* 打印本本库信息
*/
print_version_info();

/*
* get 方法访问百度并获取数据
*/
baidu_get_test();

curl_global_cleanup();

return 0;
}


static size_t baidu_get_test_cb(void *buffer, size_t size, size_t nmemb, void *user_p)
{
FILE *fp = (FILE *)user_p;
size_t return_size = fwrite(buffer, size, nmemb, fp);
return return_size;
}

static size_t head_process_data(char *buffer, size_t size, size_t nitems, void *userdata)
{
char *head_line = userdata;

printf("nitems = %d\n", nitems);

strncpy(head_line, (const char *)buffer, nitems);
*(head_line + nitems) = 0;

printf("head info : %s", head_line);

return nitems;
}


static void baidu_get_test(void)
{
/*
* 获取一个easy句柄,后面通过这个句柄进行通信
*/
CURL *easy_handle = curl_easy_init();

if(!easy_handle) {
printf("curl_easy_init Err \n");
curl_global_cleanup();
return ;
}

/*
* 打开一个data.html文件,用于存储百度返回的数据
*/
FILE *fp = fopen("data.html", "w+");
char *head_line = (char *)malloc(100*1024);


/*
* 设置libcurl的选项,没有指定http访问方法,libcurl默认使用get方法
*/
curl_easy_setopt(easy_handle, CURLOPT_URL, "http://www.baidu.com");
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, baidu_get_test_cb);
curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, fp);

/*
* 增加调试功能,可以查看libcurl的执行过程
*/
curl_easy_setopt(easy_handle, CURLOPT_VERBOSE, 1);

/*
* 接收http头信息
*/
curl_easy_setopt(easy_handle, CURLOPT_HEADERFUNCTION, head_process_data);
curl_easy_setopt(easy_handle, CURLOPT_HEADERDATA, head_line);


struct curl_slist *plist;
plist = curl_slist_append(0, "name: huohongpeng");
/*
* 删除Host字段
*/
curl_slist_append(plist, "Host:");
/*
* 添加没有内容的字段
*/
curl_slist_append(plist, "Content-Type;");
/*
* 修改Accept: application/json
*/
curl_slist_append(plist, "Accept: application/json");
curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, plist);

/*
* 执行访问
*/
CURLcode code = curl_easy_perform(easy_handle);

if(CURLE_OK != code) {
printf("curl_easy_perform %d\n", code);
}

/*
* 获取信息
*/
double tmp = 0;
code = curl_easy_getinfo(easy_handle, CURLINFO_TOTAL_TIME, &tmp);
printf("CURLINFO_TOTAL_TIME = %lf\n", tmp);

curl_easy_getinfo(easy_handle, CURLINFO_CONNECT_TIME, &tmp);
printf("CURLINFO_CONNECT_TIME = %lf\n", tmp);

curl_easy_getinfo(easy_handle, CURLINFO_SIZE_DOWNLOAD, &tmp);
printf("CURLINFO_SIZE_DOWNLOAD = %d\n", (int)tmp);


free(head_line);

fclose(fp);
curl_slist_free_all(plist);
/*
* 最后记得释放句柄
*/
curl_easy_cleanup(easy_handle);
}


static void print_version_info(void)
{
curl_version_info_data *version_info = curl_version_info(CURLVERSION_NOW);

printf("version:%s\n", version_info->version);
printf("host:%s\n", version_info->host);
printf("ssl_version:%s\n", version_info->ssl_version);
}