cURL-03-cURL的幾種語言支持

一、基於 C 的 HTTP 客戶端

C API 在 libcurl 功能上提供了兩個 API。easy 接口是一個簡單的同步 API(意味着當您使用請求調用 libcurl 時,將能夠滿足您的請求,直到完成或發生錯誤)。多接口可以進一步控制 libcurl,您的應用程序可以執行多個同步傳輸,並控制 libcurl 何時何地移動數據。

該示例使用 easy 接口。該 API 還能控制數據移動過程(使用回調),但正如其名稱所示,使用起來非常簡單。下面請看HTTP 的 C 語言示例,使用 libcurl easy 接口的 C HTTP 客戶端。

#include <stdio.h> 
#include <string.h> 
#include <curl/curl.h> 
 
#define MAX_BUF     65536 
 
char wr_buf[MAX_BUF+1]; 
int  wr_index; 
 
/* 
* Write data callback function (called within the context of 
* curl_easy_perform. 
*/ 
size_t write_data( void *buffer, size_t size, size_t nmemb, void *userp ) 
{ 
 int segsize = size * nmemb; 
 
 /* Check to see if this data exceeds the size of our buffer. If so, 
  * set the user-defined context value and return 0 to indicate a 
  * problem to curl. 
  */ 
 if ( wr_index + segsize > MAX_BUF ) { 
   *(int *)userp = 1; 
   return 0; 
 } 
 
 /* Copy the data from the curl buffer into our buffer */ 
 memcpy( (void *)&wr_buf[wr_index], buffer, (size_t)segsize ); 
 
 /* Update the write index */ 
 wr_index += segsize; 
 
 /* Null terminate the buffer */ 
 wr_buf[wr_index] = 0; 
 
 /* Return the number of bytes received, indicating to curl that all is okay */ 
 return segsize; 
} 
 
 
/* 
* Simple curl application to read the index.html file from a Web site. 
*/ 
int main( void ) 
{ 
 CURL *curl; 
 CURLcode ret; 
 int  wr_error; 
 
 wr_error = 0; 
 wr_index = 0; 
 
 /* First step, init curl */ 
 curl = curl_easy_init(); 
 if (!curl) { 
   printf("couldn't init curl\n"); 
   return 0; 
 } 
 
 /* Tell curl the URL of the file we're going to retrieve */ 
 curl_easy_setopt( curl, CURLOPT_URL, "www.exampledomain.com" ); 
 
 /* Tell curl that we'll receive data to the function write_data, and 
  * also provide it with a context pointer for our error return. 
  */ 
 curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)&wr_error ); 
 curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_data ); 
 
 /* Allow curl to perform the action */ 
 ret = curl_easy_perform( curl ); 
 
 printf( "ret = %d (write_error = %d)\n", ret, wr_error ); 
 
 /* Emit the page if curl indicates that no errors occurred */ 
 if ( ret == 0 ) printf( "%s\n", wr_buf ); 
 
 curl_easy_cleanup( curl ); 
 
 return 0; 
}

最上方是必需的 include文件,包括 cURL 根文件。接下來,定義了兩個用於傳輸的變量。第一個變量是 wr_buf,表示將在其中寫入傳入數據的緩衝區。wr_index表示緩衝區的當前寫入索引。

轉到 main函數,該函數使用 easy API 進行設置。所有 cURL 調用都通過維護特定請求狀態的句柄進行操作。這稱爲 CURL指針引用。本例還創建一個特殊的返回碼,稱爲 CURLcode。在使用任何 libcurl 函數之前,您需要調用 curl_easy_init獲取 CURL句柄。接下來,注意 curl_easy_setopt調用的數量。它們爲特定的操作配置句柄。對於這些調用,您提供句柄、命令和選項。首先,本例使用 CURLOPT_URL指定要獲取的 URL。然後,它使用 CURL_WRITEDATA提供一個上下文變量(在本例中,它是內部的 write 錯誤變量)。最後,它使用 CURLOPT_WRITEFUNCTION指定數據可用時應該調用的函數。在啓動 API 之後,API 將使用它讀取的數據多次調用該函數。

要開始傳輸,調用 curl_easy_perform。它的工作是根據之前的配置執行傳輸。調用該函數時,在完成傳輸或發生錯誤之前該函數不會返回。main的最後一步是提交返回狀態,提交頁面讀取,最後使用 curl_easy_cleanup清除(當使用句柄執行完操作後)。

現在看看 write_data函數。該函數是針對特定操作收到數據時調用的回調。注意,當您從網站讀取數據時,將寫入該數據(write_data)。將向回調提供一個緩衝區(包含可用數據)、成員數量和大小(緩衝中可用數據總量)、上下文指針。第一個任務是確保緩衝區(wr_buf)的空間足以寫入數據。如果不夠,它將設置上下文指針並返回 0,表示出現問題。否則,它將 cURL 緩衝區的數據複製到您的緩衝區,並增加索引,指向要寫入的下一個位置。本例還終止字符串,稍後可以對其使用 printf。最後,它返回 libcurl 操作的字節數量。這將告訴 libcurl 數據被提取,它也可以丟棄該數據。這就是從網站將文件讀取到內存的相對簡單的方法。

二、基於 Python 的 HTTP 客戶端

Python 是一種非常有用的面向對象的腳本語言,在原型化和構建生產軟件方面非常突出。示例假設您較熟悉 Python,但使用不多,因此不要期望過高。

這個簡單的 Python HTTP 客戶端使用 pycurl,如下:

使用 libcurl 的 pycurl接口的 Python HTTP 客戶端

import sys 
import pycurl 
 
wr_buf = ''
 
def write_data( buf ): 
    global wr_buf 
    wr_buf += buf 
 
def main(): 
    c = pycurl.Curl() 
    c.setopt( pycurl.URL, 'http://www.exampledomain.com' ) 
    c.setopt( pycurl.WRITEFUNCTION, write_data ) 
 
    c.perform() 
 
    c.close() 
 
main() 
sys.stdout.write(wr_buf)

這比 C 語言版本簡單的多。它首先導入必需的模塊(用於標準系統的 sys和 pycurl模塊)。接下來,它定義 write 緩衝區(wr_buf)。像 C 程序中一樣,聲明一個 write_data函數。注意,該函數只有一個參數:從 HTTP 服務器中讀取的數據緩衝區。我將該緩衝區連接到全局 write 緩衝區。main函數首先創建一個 Curl句柄,然後使用 setopt方法爲傳輸定義 URL和 WRITEFUNCTION。它調用 perform方法啓動傳輸並關閉句柄。最後,它調用 main函數,並將 write 緩衝區提交到 stdout。注意,在這種情況下,不需要錯誤上下文指針,因爲使用了 Python 字符串連接,這就是說您不會使用大小固定的字符串。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章