libcurl库的安装和使用
libcurl簡介:
libcurl是一個(gè)跨平臺(tái)的網(wǎng)絡(luò)協(xié)議庫,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 協(xié)議。libcurl同樣支持HTTPS證書授權(quán),HTTP POST, HTTP PUT, FTP 上傳, HTTP基本表單上傳,代理,cookies,和用戶認(rèn)證。libcurl的官網(wǎng) 、庫下載。這種庫使用的時(shí)候就像使用wiringPi庫一樣,編寫完代碼需要鏈接這個(gè)庫,所以要先下載這個(gè)庫。
libcurl的使用(其實(shí)和socket編程時(shí)一樣,都需要一定的步驟):
- 調(diào)用curl_global_init()初始化libcurl,(就像初始化套接字)
- 調(diào)用curl_easy_init()函數(shù)得到 easy interface型指針(這個(gè)指針用來各種配置)
- 調(diào)用curl_easy_setopt()設(shè)置傳輸選項(xiàng)(通過調(diào)用curl_easy_setopt這個(gè)函數(shù)來對(duì)指針進(jìn)行各種配置,比如:請(qǐng)求的方式)
- 根據(jù)curl_easy_setopt()設(shè)置的傳輸選項(xiàng),實(shí)現(xiàn)回調(diào)函數(shù)以完成用戶特定任務(wù)
- 調(diào)用curl_easy_perform()函數(shù)進(jìn)行訪問請(qǐng)求
- 調(diào)用curl_easy_cleanup()釋放內(nèi)存
libcurl等第三方庫的通用編譯方法:
-
首先進(jìn)入libcurl庫得下載界面,點(diǎn)擊下載libcurl庫
-
下載完成后通過共享文件夾或者FileZill或者直接拖拽將壓縮包移動(dòng)到虛擬機(jī)。我這里將壓縮包拖拽至虛擬機(jī)的桌面,然后使用指令:mv ~/Desktop/curl-7.71.1.tar.bz2 .(~表示工作路徑就是/home/fhn這個(gè)路徑)將壓縮包移動(dòng)到我新建的httpHandler這個(gè)文件夾里面,然后使用指令:tar vxf curl-7.71.1.tar.bz2解壓這個(gè)文件夾,解壓后進(jìn)入文件夾,如下圖所示(之后用到的開源的庫基本都是這樣的,內(nèi)容形式差不多):
-
那么如何使用這種開源的壓縮包呢?這個(gè)文件夾下面有一個(gè)README文件夾,里面有對(duì)庫的一些說明,如下圖所示,由下圖可知,我們使用libcurl庫時(shí)可以查看curl.1手冊(cè)或者M(jìn)ANUAL document這個(gè)手冊(cè)
-
這里我用有道翻譯將這些英文進(jìn)行了簡單地翻譯:
自述:Curl是一個(gè)命令行工具,用于傳輸由URL(網(wǎng)址)指定的數(shù)據(jù)語法。通過閱讀curl了解如何使用curl。手冊(cè)頁或手冊(cè)文檔。通過閱讀install了解如何安裝Curl文檔。Libcurl是curl用來完成其工作的庫。它很容易可被您的軟件使用。閱讀libcurl。3手冊(cè)頁學(xué)習(xí)如何!你可以在FAQ文檔中找到最常見問題的答案。研究copy文件中的分發(fā)條款和類似條款。如果你分配Curl二進(jìn)制文件或其他涉及l(fā)ibcurl的二進(jìn)制文件,您可能會(huì)喜歡LICENSE-MIXING文檔。所有這些文檔以及更多文檔都可以在docs/目錄中找到。聯(lián)系:如果您有問題、疑問、想法或建議,請(qǐng)與我們聯(lián)系通過郵寄到一個(gè)合適的郵寄名單。參見http//curl.haxx.se/mail/該項(xiàng)目的所有貢獻(xiàn)者都列在THANKS文檔中。網(wǎng)站:訪問curl網(wǎng)站獲取最新消息和下載:https://curl.haxx.se/,GIT:要從GIT服務(wù)器上下載最新的源代碼,請(qǐng)這樣做:git克隆https://github.com/curl/curl.git,(您將創(chuàng)建一個(gè)名為curl的目錄,并填充源代碼)。安全問題:通過我們的HackerOne頁面報(bào)告可疑的安全問題,而不是在公共場合!https://hackerone.com/curl請(qǐng)注意:Curl包含的源代碼是版權(quán)所有? 1998, 1999。終于Tekniska Hogskolan。在此附上此通知是為了遵守分布條件。 -
通過閱讀README我們并沒有找到如何使用這個(gè)庫,然后進(jìn)入到docs這個(gè)文件夾,這個(gè)文件夾是對(duì)RADME的一個(gè)補(bǔ)充,在這個(gè)文件夾下面我們會(huì)看到README里面提到的curl1.1這個(gè)API相關(guān)的手冊(cè),還有INSTALL(這個(gè)一定要看,有時(shí)候他會(huì)和README都放在解壓后的文件夾里面,有時(shí)候會(huì)放在docs里面)。
-
打開INSTALL后看到,提示說如何編譯(compile)這個(gè)庫請(qǐng)看INSTALL.md這個(gè)文件,打開這個(gè)文件后,里面有介紹如何安裝編譯后的libcurl庫,然后下面可以看到在UNIX環(huán)境下面如何進(jìn)行安裝,如下圖所示,./config就是配置的一個(gè)東西,就是將庫安裝到哪里,若后面不跟任何的參數(shù),就是默認(rèn)安裝(可能安裝在/usr/lib或者/usr/include下面)。make就是編譯的意思,make install就是將編譯后的東西拷貝到根目錄的相關(guān)文件夾下面。如果默認(rèn)安裝的話可能需要root權(quán)限因?yàn)?#xff1a;默認(rèn)可能安裝在/usr/lib或者/usr/include下面,而訪問這兩個(gè)文件夾需要root權(quán)限。
-
當(dāng)然一般不安裝在默認(rèn)的路徑下面,可以通過下圖方式指定安裝路徑
-
通過指令:./configure --help可以查看configure都支持哪些功能參數(shù),其中下面的HOST這個(gè)指令可以指定交叉編譯的編譯器(若不指定交叉編譯工具默認(rèn)使用gcc編譯工具)。
-
通過以下指令:./configure --prefix=$PWD/_install進(jìn)行指定位置的安裝,安裝的時(shí)候會(huì)生成一個(gè)_install文件夾,庫將會(huì)被安裝到這個(gè)文件夾下面,安裝過程中沒有出現(xiàn)任何error表示安裝成功,然后使用指令:make進(jìn)行編譯,然后使用使用指令:make install進(jìn)行拷貝,然后會(huì)發(fā)現(xiàn)當(dāng)前文件夾下面生成了一個(gè)_install文件夾,然后進(jìn)入到該文件夾,如下圖所示:
調(diào)用libcurl庫訪問百度主頁并將數(shù)據(jù)保存到文件中:
程序代碼:
#include <stdio.h> #include <curl/curl.h> #define true 1 #define false 0 typedef unsigned int bool; bool getUrl(char *filename) {CURL *curl;CURLcode res;FILE *fp;if ((fp = fopen(filename, "w")) == NULL) // 返回結(jié)果用文件存儲(chǔ)return false;struct curl_slist *headers = NULL;headers = curl_slist_append(headers, "Accept: Agent-007");curl = curl_easy_init(); // 初始化if (curl){//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");// 代理curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改協(xié)議頭curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //將返回的http頭輸出到fp指向的文件curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp); //將返回的html主體數(shù)據(jù)輸出到fp指向的文件res = curl_easy_perform(curl); // 執(zhí)行if (res != 0) {curl_slist_free_all(headers);curl_easy_cleanup(curl);}fclose(fp);return true;} } int main(void) {getUrl("/tmp/get.html"); }- 使用指令:gcc demo1.c -o demo1 -I ~/httphandler/curl-7.71.1/_install/include -L ~/httphandler/curl-7.71.1/_install/lib/ -lcurl進(jìn)行編譯,-I是指定頭文件的查找路徑,-L是指定庫文件的查找路徑,同時(shí)還要-l curl,編譯后的執(zhí)行文件在執(zhí)行的時(shí)候出現(xiàn)以下圖中錯(cuò)誤:因?yàn)樵诔绦驁?zhí)行的時(shí)候,默認(rèn)去/usr/lib去找?guī)?#xff0c;然而沒有找到,所以我們要設(shè)置動(dòng)態(tài)庫的環(huán)境遍變量:使用指令:export LD_LIBRARY_PATH=庫的路徑,這種方法臨時(shí)有效,永久生效的環(huán)境變量設(shè)置,編輯/etc/profile即可。也可以修改工作目錄下的.bashrc 文件。
- 通過以上設(shè)置然后再執(zhí)行程序:可以看到/tmp/get.html這個(gè)文件夾里面有從百度網(wǎng)頁獲取的html代碼:
libcurl庫函數(shù)介紹:
- curl_global_init(long flags)函數(shù):
- void curl_global_cleanup(void)函數(shù): 結(jié)束libcurl使用的時(shí)候,用來對(duì)curl_global_init做的工作清理。類似于close的函數(shù)。注意:雖然libcurl是線程安全的,但curl_global_cleanup是不能保證線程安全的,所以不要在每個(gè)線程中都調(diào)用curl_global_init,應(yīng)該將該函數(shù)的調(diào)用放在主線程中。
- char * curl_version( )函數(shù): 打印當(dāng)前l(fā)ibcurl庫的版本。
- CURL * curl_easy_init( )函數(shù): curl_easy_init用來初始化一個(gè)CURL的指針(有些像返回FILE類型的指針一樣). 相應(yīng)的在調(diào)用結(jié)束時(shí)要用url_easy_cleanup函數(shù)清理.一般curl_easy_init意味著一個(gè)會(huì)話的開始. 它會(huì)返回一個(gè)easy_handle(CURL*對(duì)象), 一般都用在easy系列的函數(shù)中.
- void curl_easy_cleanup(CURL * handle)函數(shù): 這個(gè)調(diào)用用來結(jié)束一個(gè)會(huì)話.與curl_easy_init配合著用. 參數(shù):CURL類型的指針.
- CURLcode curl_easy_setopt(CURL * handle, CURLoption option, parameter)函數(shù):
- CURLcode curl_easy_perform(CURL * handle)函數(shù): 在初始化CURL類型的指針以及curl_easy_setopt完成后調(diào)用. 就像字面的意思所說perform就像是個(gè)舞臺(tái).讓我們?cè)O(shè)置的option 運(yùn)作起來.參數(shù):CURL類型的指針.
curl_easy_setopt函數(shù)部分選項(xiàng)介紹:
本節(jié)主要介紹curl_easy_setopt中跟http相關(guān)的參數(shù)。該函數(shù)是curl中非常重要的函數(shù),curl所有設(shè)置都是在該函數(shù)中完成的,該函數(shù)的設(shè)置選項(xiàng)眾多,注意本節(jié)的闡述的只是部分常見選項(xiàng)。
-
CURLOPT_URL 設(shè)置訪問URL。比如:curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com")
-
CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
回調(diào)函數(shù)原型為:size_t function( void *ptr, size_t size, size_t nmemb, void *stream); 函數(shù)將在libcurl接收到數(shù)據(jù)后被調(diào)用,因此函數(shù)多做數(shù)據(jù)保存的功能,如處理下載文件。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函數(shù)中的stream指針的來源。如果你沒有通過CURLOPT_WRITEFUNCTION屬性給easy handle設(shè)置回調(diào)函數(shù),libcurl會(huì)提供一個(gè)默認(rèn)的回調(diào)函數(shù),它只是簡單的將接收到的數(shù)據(jù)打印到標(biāo)準(zhǔn)輸出。你也可以通過 CURLOPT_WRITEDATA屬性給默認(rèn)回調(diào)函數(shù)傳遞一個(gè)已經(jīng)打開的文件指針,用于將數(shù)據(jù)輸出到文件里。 -
CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
回調(diào)函數(shù)原型為 size_t function( void *ptr, size_t size,size_t nmemb, void *stream); libcurl一旦接收到http 頭部數(shù)據(jù)后將調(diào)用該函數(shù)。CURLOPT_WRITEDATA 傳遞指針給libcurl,該指針表明CURLOPT_HEADERFUNCTION 函數(shù)的stream指針的來源。 -
CURLOPT_READFUNCTION 、CURLOPT_READDATA
libCurl需要讀取數(shù)據(jù)傳遞給遠(yuǎn)程主機(jī)時(shí)將調(diào)用CURLOPT_READFUNCTION指定的函數(shù),函數(shù)原型是:size_t function(void *ptr, size_t size, size_t nmemb,void *stream). CURLOPT_READDATA 表明CURLOPT_READFUNCTION函數(shù)原型中的stream指針來源。 -
CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
跟數(shù)據(jù)傳輸進(jìn)度相關(guān)的參數(shù)。CURLOPT_PROGRESSFUNCTION 指定的函數(shù)正常情況下每秒被libcurl調(diào)用一次,為了使CURLOPT_PROGRESSFUNCTION被調(diào)用,CURLOPT_NOPROGRESS必須被設(shè)置為false,CURLOPT_PROGRESSDATA指定的參數(shù)將作為CURLOPT_PROGRESSFUNCTION指定函數(shù)的第一個(gè)參數(shù), - -
CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于設(shè)置傳輸時(shí)間,CURLOPT_CONNECTIONTIMEOUT 設(shè)置連接等待時(shí)間 -
CURLOPT_FOLLOWLOCATION,設(shè)置重定位URL
curl_easy_perform 函數(shù)說明(error 狀態(tài)碼):
該函數(shù)是完成curl_easy_setopt指定的所有選項(xiàng),本節(jié)重點(diǎn)介紹curl_easy_perform的返回值。返回0意味一切ok,非0代表錯(cuò)誤發(fā)生。主要錯(cuò)誤碼說明:
- CURLE_OK 任務(wù)完成一切都好
- CURLE_UNSUPPORTED_PROTOCOL 不支持的協(xié)議,由URL的頭部指定
- CURLE_COULDNT_CONNECT 不能連接到remote 主機(jī)或者代理
- CURLE_REMOTE_ACCESS_DENIED 訪問被拒絕
- CURLE_HTTP_RETURNED_ERROR Http返回錯(cuò)誤
- CURLE_READ_ERROR 讀本地文件錯(cuò)誤
要獲取詳細(xì)的錯(cuò)誤描述字符串,可以通過const char *curl_easy_strerror(CURLcode errornum ) 這個(gè)函數(shù)取得.
參考博文:http協(xié)議之libcurl
總結(jié)
以上是生活随笔為你收集整理的libcurl库的安装和使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。