libcurl庫(kù)是一個(gè)實(shí)現(xiàn)了各種客戶端協(xié)議的網(wǎng)絡(luò)編程庫(kù)。目前它支持12種以上的協(xié)議,包括 FTP、HTTP、Telnet以及其他安全變體。
如果您有 10 年以上的腳本語(yǔ)言經(jīng)驗(yàn),您就會(huì)注意到它們的標(biāo)記有很大的變化。Python、Ruby、Perl 等這些腳本語(yǔ)言不僅包含套接字層(C 或 C++ 中也有),還包含了應(yīng)用層協(xié)議 API。這些腳本語(yǔ)言合并了高級(jí)功能,可以創(chuàng)建 HTTP 服務(wù)器或客戶端。libcurl 庫(kù)為 C 和 C++ 之類的語(yǔ)言添加了類似的功能,但是它可以在不同的語(yǔ)言之間移植。在所有它支持的語(yǔ)言中都能找到與 libcurl 相當(dāng)?shù)男袨椋怯捎谶@些語(yǔ)言的差異很大(設(shè)想一下 C 和 Scheme),提供這些行為的方式也很不相同。
libcurl 庫(kù)以 API 的形式封裝各種客戶端協(xié)議,因此它可以被高級(jí)語(yǔ)言使用(如今已超過(guò) 30 種)。下面的示例研究使用 C 構(gòu)建的簡(jiǎn)單 HTTP 客戶端(適合構(gòu)建 Web 爬行器)。
C API 在 libcurl 功能上提供了兩個(gè) API。easy 接口是一個(gè)簡(jiǎn)單的同步 API(意味著當(dāng)您使用請(qǐng)求調(diào)用 libcurl 時(shí),將能夠滿足您的請(qǐng)求,直到完成或發(fā)生錯(cuò)誤)。多接口可以進(jìn)一步控制 libcurl,您的應(yīng)用程序可以執(zhí)行多個(gè)同步傳輸,并控制 libcurl 何時(shí)何地移動(dòng)數(shù)據(jù)。
該示例使用 easy 接口。該 API 還能控制數(shù)據(jù)移動(dòng)過(guò)程(使用回調(diào)),但正如其名稱所示,使用起來(lái)非常簡(jiǎn)單。清單 3 提供了 HTTP 的 C 語(yǔ)言示例。
使用 libcurl easy 接口的 C HTTP 客戶端
最上方是必需的 include
文件,包括 cURL 根文件。接下來(lái),我定義了兩個(gè)用于傳輸?shù)淖兞?。第一個(gè)變量是 wr_buf
,表示將在其中寫入傳入數(shù)據(jù)的緩沖區(qū)。wr_index
表示緩沖區(qū)的當(dāng)前寫入索引。
轉(zhuǎn)到 main
函數(shù),該函數(shù)使用 easy API 進(jìn)行設(shè)置。所有 cURL 調(diào)用都通過(guò)維護(hù)特定請(qǐng)求狀態(tài)的句柄進(jìn)行操作。這稱為 CURL
指針引用。本例還創(chuàng)建一個(gè)特殊的返回碼,稱為 CURLcode
。在使用任何 libcurl 函數(shù)之前,您需要調(diào)用 curl_easy_init
獲取 CURL
句柄。接下來(lái),注意 curl_easy_setopt
調(diào)用的數(shù)量。它們?yōu)樘囟ǖ牟僮髋渲镁浔?。?duì)于這些調(diào)用,您提供句柄、命令和選項(xiàng)。首先,本例使用 CURLOPT_URL
指定要獲取的 URL。然后,它使用 CURL_WRITEDATA
提供一個(gè)上下文變量(在本例中,它是內(nèi)部的 write 錯(cuò)誤變量)。最后,它使用 CURLOPT_WRITEFUNCTION
指定數(shù)據(jù)可用時(shí)應(yīng)該調(diào)用的函數(shù)。在啟動(dòng) API 之后,API 將使用它讀取的數(shù)據(jù)多次調(diào)用該函數(shù)。
要開始傳輸,調(diào)用 curl_easy_perform
。它的工作是根據(jù)之前的配置執(zhí)行傳輸。調(diào)用該函數(shù)時(shí),在完成傳輸或發(fā)生錯(cuò)誤之前該函數(shù)不會(huì)返回。main
的最后一步是提交返回狀態(tài),提交頁(yè)面讀取,最后使用 curl_easy_cleanup
清除(當(dāng)使用句柄執(zhí)行完操作后)。
現(xiàn)在看看 write_data
函數(shù)。該函數(shù)是針對(duì)特定操作收到數(shù)據(jù)時(shí)調(diào)用的回調(diào)。注意,當(dāng)您從網(wǎng)站讀取數(shù)據(jù)時(shí),將寫入該數(shù)據(jù)(write_data
)。將向回調(diào)提供一個(gè)緩沖區(qū)(包含可用數(shù)據(jù))、成員數(shù)量和大小(緩沖中可用數(shù)據(jù)總量)、上下文指針。第一個(gè)任務(wù)是確保緩沖區(qū)(wr_buf
)的空間足以寫入數(shù)據(jù)。如果不夠,它將設(shè)置上下文指針并返回 0,表示出現(xiàn)問(wèn)題。否則,它將 cURL 緩沖區(qū)的數(shù)據(jù)復(fù)制到您的緩沖區(qū),并增加索引,指向要寫入的下一個(gè)位置。本例還終止字符串,稍后可以對(duì)其使用 printf
。最后,它返回 libcurl 操作的字節(jié)數(shù)量。這將告訴 libcurl 數(shù)據(jù)被提取,它也可以丟棄該數(shù)據(jù)。這就是從網(wǎng)站將文件讀取到內(nèi)存的相對(duì)簡(jiǎn)單的方法。
聯(lián)系客服