亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

使用 cURL 和 libcurl 通過 Internet 進行對話

系統 1576 0

cURL 是一個命令行工具,可以對文件傳輸使用許多協議,包括 HTTP、FTP、Secure Copy (SCP)、Telnet 等等。但是,除了可以用命令行通過 Internet 與端點對話外,還可以使用 libcurl 編寫簡單或復雜的程序,以自動化執行應用層的協議任務。本文將介紹 cURL 命令行工具,然后向您展示如何使用 libcurl 以及 C 和 Python 構建一個 HTTP 客戶端。

開發 HTTP 和 FTP 之類依賴于應用層協議的應用程序并不復雜,但也不簡單。進一步講,這不是應用程序的重點,因為大部分情況下,協議之上的內容才是真正重要的內容。因 此,libcurl 引起了許多人的興趣,因為它的重點是應用程序而不是開發的各個方面。注意,很少有應用程序開發自己的 TCP/IP 堆棧,所以老話重提:盡可能重用以最小化開發安排并提高應用程序的可靠性。

本文首先簡單介紹應用層協議,然后介紹 cURL、libcurl 并解釋它們的用法。

Web 協議

如 今構建應用程序已與過去大不相同。現在的應用程序需要能夠通過網絡或 Internet 進行通訊(提供人類可用的網絡 API 或接口),還要能支持用戶腳本化以提高靈活性?,F代應用程序通常使用 HTTP 公開 Web 接口,并通過 Simple Mail Transport Protocol (SMTP) 提供警告通知。這些協議允許您將 Web 瀏覽器指向設備以獲得配置或狀態信息,并從設備或常用的電子郵件客戶端接收標準電子郵件(分別通過 HTTP 和 SMTP)。

這些 Web 服務通常構建在網絡堆棧的套接字層上(見圖 1)。套接字層實現一個最先出現在 Berkeley Software Distribution (BSD) 操作系統上的 API,并提取底層傳輸和網絡層協議的詳細信息。


圖 1. 網絡堆棧和 libcurl
圖 1. 網絡堆棧和 libcurl

Web 服務發生在客戶端和服務器之間的協議對話中。在 HTTP 上下文中,服務器是終端設備,客戶端是位于端點上的瀏覽器。對于 SMTP,服務器是郵件網關或端點用戶,客戶端是終端設備。在某些情況下,協議對話發生在兩個步驟(請求和響應)中,但另一些情況下,需要協商和通訊的通 信量更多。這種協商可能增加了大量復雜性,這可以通過 API 進行抽象,比如 libcurl。

cURL 最初的設計初衷是使用不同的協議(比如 FTP、HTTP、SCP 等)在端點之間移動文件。它最初是一個命令行實用工具,但現在也是一個綁定了 30 多種語言的庫。因此,現在不僅可以通過 shell 使用 cURL,您還可以構建合并了這個重要功能的應用程序。libcurl 庫也是可以移植的,支持 Linux?、IBM?AIX?操作系統、BSD、Solaris 以及許多其他 UNIX?變體。

獲取和安裝 cURL/libcurl

獲取和安裝 libcurl 非常簡單,取決于您所運行的 Linux 發行版。如果運行的是 Ubuntu,您可以使用 apt-get 輕松安裝這些包。以下行演示了如何為 libcurl 安裝 libcurl 和 Python 綁定:

               $ 
              
                sudo apt-get install libcurl3
              
              

 $ 
              
                sudo apt-get install python-pycurl
              
            

?

apt-get 實用工具確保該過程滿足所有的依賴關系。

在命令行中使用 cURL

cURL 最開始是一個命令行工具,可以使用 Uniform Resource Locator (URL) 語法執行數據傳輸。考慮到它在命令行上的流行度,后來創建了一個可以在應用程序中生成這些行為的庫。如今,命令行 cURL 是 cURL 庫的包裝器。本文首先研究 cURL 作為命令行的功能,然后深入探討如何將它作為庫使用。

cURL 的兩種常見用法是使用 HTTP 和 FTP 協議進行文件傳輸。cURL 為這些協議提供一個簡單的接口。要使用 HTTP 從網站獲取文件,只需告訴 cURL 您要將網頁寫入到其中的本地文件的文件名、網站的 URL 以及要獲取的文件。讓我們看一下清單 1 中的簡單命令行示例。


清單 1. 使用 cURL 從網站獲取文件的示例

              				
 $ 
              
                curl -o test html www.exampledomain.com
              
              

  % Total    % Received % Xferd  Average Speed    Time    Time     Time    Current 
                                 Dload  Upload    Total   Spent    Left    Speed 
 100 43320  100 43320    0     0  55831       0 --:--:-- --:--:-- --:--:--  89299 
 $ 

            

?

注意,由于我指定了域而不是文件,我將獲得根文件(index.html)。要使用 cURL 將該文件移動到 FTP 站點,可以使用 -T 選項指定要上傳的文件,然后提供 FTP 站點的 URL 以及文件的路徑。


清單 2. 使用 cURL 將 文件上傳 到 FTP 站點的示例

              				
 $ 
              
                curl -T test.html ftp://user:password@ftp.exampledomain.com/ftpdir/
              
              

  % Total    % Received % Xferd  Average Speed    Time    Time     Time    Current 
                                 Dload  Upload    Total   Spent    Left    Speed 
 100 43320    0     0  100 43320      0  38946   0:00:01 0:00:01  --:--:--    124k 
 $ 

            

?

是不是很簡單?學習了一些模式之后您會發現,cURL 使用起來非常簡單。但是您可以使用的選項非常多 —在 cURL 命令行中請求幫助(使用 --help )可以得到 129 行選項。如果您覺得這還不算太多,那么還有一大批其他控制選項(從詳細度到安全性),以及特定于協議的配置項。

從開發人員的角度看,這還不算是 cURL 最令人興奮的地方。讓我們深入了解 cURL 庫,學習如何向應用程序添加文件傳輸協議。

作為庫的 cURL

如 果您有 10 年以上的腳本語言經驗,您就會注意到它們的標記有很大的變化。Python、Ruby、Perl 等這些腳本語言不僅包含套接字層(C 或 C++ 中也有),還包含了應用層協議 API。這些腳本語言合并了高級功能,可以創建 HTTP 服務器或客戶端。libcurl 庫為 C 和 C++ 之類的語言添加了類似的功能,但是它可以在不同的語言之間移植。在所有它支持的語言中都能找到與 libcurl 相當的行為,但是由于這些語言的差異很大(設想一下 C 和 Scheme),提供這些行為的方式也很不相同。

libcurl 庫以 API 的形式封裝清單 1 和清單 2 中描述的行為,因此它可以被高級語言使用(如今已超過 30 種)。本文提供了 libcurl 的兩個示例。第一個示例研究使用 c 構建的簡單 HTTP 客戶端(適合構建 Web 爬行器),第二個示例是一個使用 Python 創建的簡單 HTTP 客戶端。

基于 C 的 HTTP 客戶端

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

該示例使用 easy 接口。該 API 還能控制數據移動過程(使用回調),但正如其名稱所示,使用起來非常簡單。清單 3 提供了 HTTP 的 C 語言示例。


清單 3. 使用 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 客戶端

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

這個簡單的 Python HTTP 客戶端使用 pycurl ,如清單 4 所示。


清單 4. 使用 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 字符串連接,這就是說您不會使用大小固定的字符串。

結束語

本文僅僅簡單介紹了 libcurl,介紹了它支持的多種協議和語言。希望這能夠展示它如何輕松構建使用應用層協議(如 HTTP)的應用程序。libcurl 網站提供了很多示例和有用的文檔。下一次開發 Web 瀏覽器、爬行器或其他有應用層協議要求的應用程序時,試試 libcurl。它一定能大大減少您的開發時間,并找回編碼的樂趣。

使用 cURL 和 libcurl 通過 Internet 進行對話


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本精品一区二区三区视频 | 国产精品四虎视频一区 | 一区二区三区免费在线视频 | 亚洲精品天堂自在久久77 | 性一交一乱一视频免费看 | 国产高清一区二区三区视频 | 亚洲欧美日韩久久精品第一区 | 欧美在线播放成人免费 | 亚洲免费一级视频 | 国产色视频一区二区三区 | 免费国产一区 | 亚洲午夜久久久久中文字幕久 | 国产人成精品综合欧美成人 | 一级特黄aaa免费 | 精品国产一二三区在线影院 | 中国一级特黄aa毛片大片 | 国产精品午夜免费福利视频 | 国产乳摇福利视频在线观看 | 国产一级精品高清一级毛片 | 在线 | 一区二区三区四区 | 久久99精品视免费看 | 99热这里只有精品国产免费 | 欧美成人性色xxxx视频 | 91精品久久久久含羞草 | 偷偷操不一样的久久 | 修修视频在线观看 | 香蕉视频免费在线观看 | 不卡影院在线观看 | 国产一区二区日韩欧美在线 | 国产精品亚洲一区二区在线观看 | 日本精品视频网站 | 婷婷国产成人久久精品激情 | 国产福利91精品一区二区 | 福利姬视频在线观看 | 中文字幕一区二区三区永久 | 久久成人亚洲香蕉草草 | 国产精品天天操 | 欧美一级一毛片 | 久久精品免费i 国产 | 国产高清视频青青青在线 | 精品免费福利视频 |