libcurl入门之http通信(2)
1 摘要
1.1 平臺(tái)
運(yùn)行平臺(tái):君正x2000
libcurl版本:7.68.0,通過(guò)buildroot編譯生成。
編譯器:mips-linux-gnu-gcc (gcc version 7.2.0 (Ingenic r4.0.0-gcc720 2018.02-28))
編譯主機(jī):ubuntu 18.04
?1.2 功能
http通信(1)
1.1最少的代碼實(shí)現(xiàn)http訪問(wèn)百度,這個(gè)示例將通過(guò)get方法訪問(wèn)百度,并將百度返回的結(jié)果存入data.html文件中。
http通信(2)
2.1 增加獲取libcurl庫(kù)信息
2.2 增加打印打印http響應(yīng)head數(shù)據(jù)
2.3 增加使能版本庫(kù)調(diào)試功能
?2 打印版本庫(kù)信息
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); }int main() {................/** 打印本本庫(kù)信息*/print_version_info();........return 0; }2.1 執(zhí)行結(jié)果
# ./test version:7.68.0 host:mipsel-buildroot-linux-gnu ssl_version:OpenSSL/1.1.1g3 增加調(diào)試功能
CURLOPT_VERBOSE選項(xiàng)非常有用,當(dāng)我們?cè)谡{(diào)試嵌入式系統(tǒng)的時(shí)候沒(méi)有wireshark等抓包工具,打開(kāi)CURLOPT_VERBOSE選項(xiàng)可以看到libcurl的執(zhí)行過(guò)程
/** 設(shè)置libcurl的選項(xiàng),沒(méi)有指定http訪問(wèn)方法,libcurl默認(rèn)使用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);/** 增加調(diào)試功能,可以查看libcurl的執(zhí)行過(guò)程*/curl_easy_setopt(easy_handle, CURLOPT_VERBOSE, 1);3.1 執(zhí)行結(jié)果
# ./test version:7.68.0 host:mipsel-buildroot-linux-gnu ssl_version:OpenSSL/1.1.1g * Trying 110.242.68.3:80... * TCP_NODELAY set * Connected to www.baidu.com (110.242.68.3) port 80 (#0) > GET / HTTP/1.1 Host: www.baidu.com Accept: */** Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Accept-Ranges: bytes < Cache-Control: no-cache < Connection: keep-alive < Content-Length: 14615 < Content-Type: text/html < Date: Sat, 20 Mar 2021 03:02:49 GMT < P3p: CP=" OTI DSP COR IVA OUR IND COM " < P3p: CP=" OTI DSP COR IVA OUR IND COM " < Pragma: no-cache < Server: BWS/1.1 < Set-Cookie: BAIDUID=948BD633A8A66E61E08D2D51C124E8F2:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com < Set-Cookie: BIDUPSID=948BD633A8A66E61E08D2D51C124E8F2; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com < Set-Cookie: PSTM=1616209369; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com < Set-Cookie: BAIDUID=948BD633A8A66E611382AE5374C312B9:FG=1; max-age=31536000; expires=Sun, 20-Mar-22 03:02:49 GMT; domain=.baidu.com; path=/; version=1; comment=bd < Traceid: 161620936935453114985383216040678206036 < Vary: Accept-Encoding < X-Ua-Compatible: IE=Edge,chrome=1 < * Connection #0 to host www.baidu.com left intact?
4 選項(xiàng)名:CURLOPT_HEADERFUNCTION?
CURLOPT_WRITEFUNCTION 用于接收http get返回的數(shù)據(jù)部分信息,如果想接收http get返回的頭部信息,可以使用CURLOPT_HEADERFUNCTION選項(xiàng)
4.1 原型
#include <curl/curl.h>
size_t header_callback(char *buffer, ? size_t size, ? size_t nitems, ? void *userdata);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HEADERFUNCTION, header_callback);
4.2 描述
傳遞一個(gè)上面原型中類型的回調(diào)函數(shù)指針。
當(dāng)libcurl接收頭數(shù)據(jù)的時(shí)候這個(gè)函數(shù)被調(diào)用。每一個(gè)頭部信息,都會(huì)調(diào)用一次這個(gè)函數(shù)并且只有完整的頭才會(huì)產(chǎn)生回調(diào)。使用這個(gè)函數(shù)去解析頭部是非常簡(jiǎn)單的。buffer指針指向被接被接收的數(shù)據(jù)。nitems是數(shù)據(jù)的大小,size總是1。不要認(rèn)為一行頭信息是以'\0'結(jié)束的。
userdata指針是你通過(guò)CURLOPT_HEADERDATA選項(xiàng)設(shè)置的。
回調(diào)函數(shù)必須返回實(shí)際被處理的字節(jié)個(gè)數(shù),如果回調(diào)函數(shù)返回的和傳進(jìn)來(lái)的字節(jié)數(shù)不同,libcurl將會(huì)產(chǎn)生一個(gè)錯(cuò)誤信號(hào)。這將會(huì)引起傳輸終止,并且執(zhí)行函數(shù)將會(huì)返回一個(gè)CURLE_WRITE_ERROR錯(cuò)誤。
傳入到回到函數(shù)的完整的http可能多大CURL_MAX_HTTP_HEADER?(100K)字節(jié)數(shù),這其中也包括最后一行含有的終止符。
重要的是要注意,在發(fā)起請(qǐng)求后,將為收到的所有響應(yīng)的頭調(diào)用回調(diào)函數(shù),而不僅僅是最終響應(yīng)。這包括在身份驗(yàn)證協(xié)商期間發(fā)生的所有響應(yīng)。如果你只需要對(duì)最終響應(yīng)的頭進(jìn)行操作,那么您將需要自己在回調(diào)中收集頭信息,并使用HTTP狀態(tài)行來(lái)劃分響應(yīng)邊界。
對(duì)于HTTP傳輸,狀態(tài)行和響應(yīng)主體前面的空行都包含在報(bào)頭中,并傳遞給此函數(shù)。
5 代碼實(shí)實(shí)現(xiàn)
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 : cleanclean :rm -rf testcurl_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;}/** 打印本本庫(kù)信息*/print_version_info();/** get 方法訪問(wèn)百度并獲取數(shù)據(jù)*/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) {/** 獲取一個(gè)easy句柄,后面通過(guò)這個(gè)句柄進(jìn)行通信*/CURL *easy_handle = curl_easy_init();if(!easy_handle) {printf("curl_easy_init Err \n");curl_global_cleanup();return ;}/** 打開(kāi)一個(gè)data.html文件,用于存儲(chǔ)百度返回的數(shù)據(jù)*/FILE *fp = fopen("data.html", "w+");char *head_line = (char *)malloc(100*1024);/** 設(shè)置libcurl的選項(xiàng),沒(méi)有指定http訪問(wèn)方法,libcurl默認(rèn)使用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);/** 增加調(diào)試功能,可以查看libcurl的執(zhí)行過(guò)程*/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);/** 執(zhí)行訪問(wèn)*/CURLcode code = curl_easy_perform(easy_handle);if(CURLE_OK != code) {printf("curl_easy_perform %d\n", code);}free(head_line);fclose(fp);/** 最后記得釋放句柄*/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); }?
總結(jié)
以上是生活随笔為你收集整理的libcurl入门之http通信(2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: visualSVN Server的下载和
- 下一篇: 三星s6 android 5.1.1,或