HTTP協定格式
Http(超文本傳輸協定) 是分布式雙向超媒體資訊系統應用協定,主要應用于WWW,通常HTTP資訊包括客戶機向伺服器的請求消息和伺服器向客戶機的響應消息。 http消息(請求或者響應)消息的通用格式實質相同,這兩類型的消息有一個起始行, 一個或者多個頭域,一個隻是頭域結束的空行 和 可選的消息體 組成;
HTTP的頭域包括 通用頭, 請求頭, 響應頭 和 實體頭 四個部分;
起始行: 請求消息中的起始行稱為 請求行; 由3 個字段組成, 起始行定義請求的類型:URL 和 http版本, 最後是回車 和換行符。
請求類型包括get , head, post, put, move等。
響應消息中的起始行稱為 響應行,也由3部分組成,http版本,狀态碼 和狀态短語,最後是 回車 和 換行符。
http頭域: HTTP的頭域按其所屬性質包括通用頭,請求頭,響應頭和實體頭四個部分。
通用頭域允許出現在請求或者響應消息中,包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via
請求頭域隻允許出現在請求消息中
響應頭域隻允許出現在響應消息中
實體頭部分提供有消息文檔主體資訊,主要在響應消息中發送;但是請求消息(如post和put方法)也可以使用實體題頭。
每個頭域由一個域名,冒号(:)和域值三部分組成。域名是大小寫無關的,域值前可以添加任何數量的空格符,頭域可以被擴充為多行,在每行開始處,使用至少一個空格或制表符。下表為一個典型的請求消息,下面介紹常用頭域:
在基于LibCurl的程式裡,主要采用callback function (回調函數)的形式完成傳輸任務,使用者在啟動傳輸前設定好各類參數和回調函數,當滿足條件時libcurl将調用使用者的回調函數實作特定功能。下面是利用libcurl完成傳輸任務的流程:
調用curl_global_init()初始化libcurl
調用 curl_easy_init()函數得到 easy interface型指針
調用curl_easy_setopt設定傳輸選項
根據curl_easy_setopt設定的傳輸選項,實作回調函數以完成使用者特定任務
調用curl_easy_perform()函數完成傳輸任務
調用curl_easy_cleanup()釋放記憶體
在整過過程中設定curl_easy_setopt()參數是最關鍵的,幾乎所有的libcurl程式都要使用它。
2.2 重要函數
1.CURLcode curl_global_init(long flags);
描述:
這個函數隻能用一次。(其實在調用curl_global_cleanup 函數後仍然可再用)
如果這個函數在curl_easy_init函數調用時還沒調用,它講由libcurl庫自動完成。
參數:flags
CURL_GLOBAL_ALL //初始化所有的可能的調用。
CURL_GLOBAL_SSL //初始化支援 安全套接字層。
CURL_GLOBAL_WIN32 //初始化win32套接字庫。
CURL_GLOBAL_NOTHING //沒有額外的初始化。
2 void curl_global_cleanup(void);
描述:在結束libcurl使用的時候,用來對curl_global_init做的工作清理。類似于close的函數。
3 char *curl_version( );
描述: 列印目前libcurl庫的版本。
4 CURL *curl_easy_init( );
描述:
curl_easy_init用來初始化一個CURL的指針(有些像傳回FILE類型的指針一樣). 相應的在調用結束時要用curl_easy_cleanup函數清理.
一般curl_easy_init意味着一個會話的開始. 它的傳回值一般都用在easy系列的函數中.
5 void curl_easy_cleanup(CURL *handle);
這個調用用來結束一個會話.與curl_easy_init配合着用.
參數:
CURL類型的指針.
6 CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
描述: 這個函數最重要了.幾乎所有的curl 程式都要頻繁的使用它.它告訴curl庫.程式将有如何的行為. 比如要檢視一個網頁的html代碼等.(這個函數有些像ioctl函數)參數:
1 CURL類型的指針
2 各種CURLoption類型的選項.(都在curl.h庫裡有定義,man 也可以檢視到)
3 parameter 這個參數 既可以是個函數的指針,也可以是某個對象的指針,也可以是個long型的變量.它用什麼這取決于第二個參數.
CURLoption 這個參數的取值很多.具體的可以檢視man手冊.
7 CURLcode curl_easy_perform(CURL *handle);
描述:這個函數在初始化CURL類型的指針 以及curl_easy_setopt完成後調用. 就像字面的意思所說perform就像是個舞台.讓我們設定的option 運作起來.參數:
CURL類型的指針.
3.3 curl_easy_setopt函數介紹
本節主要介紹curl_easy_setopt中跟http相關的參數。注意本節的闡述都是以libcurl作為主體,其它為客體來闡述的。
CURLOPT_URL
設定通路URL
CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
回調函數原型為:size_t function( void *ptr, size_t size, size_t nmemb, void *stream); 函數将在libcurl接收到資料後被調用,是以函數多做資料儲存的功能,如處理下載下傳檔案。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函數中的stream指針的來源。
CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
回調函數原型為 size_t function( void *ptr, size_t size,size_t nmemb, void *stream); libcurl一旦接收到http 頭部資料後将調用該函數。CURLOPT_WRITEDATA 傳遞指針給libcurl,該指針表明CURLOPT_HEADERFUNCTION 函數的stream指針的來源。
CURLOPT_READFUNCTION CURLOPT_READDATA
libCurl需要讀取資料傳遞給遠端主機時将調用CURLOPT_READFUNCTION指定的函數,函數原型是:size_t function(void *ptr, size_t size, size_t nmemb,void *stream). CURLOPT_READDATA 表明CURLOPT_READFUNCTION函數原型中的stream指針來源。
CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
跟資料傳輸進度相關的參數。CURLOPT_PROGRESSFUNCTION 指定的函數正常情況下每秒被libcurl調用一次,為了使CURLOPT_PROGRESSFUNCTION被調用,CURLOPT_NOPROGRESS必須被設定為false,CURLOPT_PROGRESSDATA指定的參數将作為CURLOPT_PROGRESSFUNCTION指定函數的第一個參數
CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于設定傳輸時間,CURLOPT_CONNECTIONTIMEOUT 設定連接配接等待時間
CURLOPT_FOLLOWLOCATION
設定重定位URL
CURLOPT_RANGE: CURLOPT_RESUME_FROM:
斷點續傳相關設定。CURLOPT_RANGE 指定char *參數傳遞給libcurl,用于指明http域的RANGE頭域,例如:
表示頭500個位元組:bytes=0-499
表示第二個500位元組:bytes=500-999
表示最後500個位元組:bytes=-500
表示500位元組以後的範圍:bytes=500-
第一個和最後一個位元組:bytes=0-0,-1
同時指定幾個範圍:bytes=500-600,601-999
CURLOPT_RESUME_FROM 傳遞一個long參數給libcurl,指定你希望開始傳遞的
偏移量。
3.4 curl_easy_perform 函數說明(error 狀态碼)
該函數完成curl_easy_setopt指定的所有選項,本節重點介紹curl_easy_perform的傳回值。傳回0意味一切ok,非0代表錯誤發生。主要錯誤碼說明:
1. CURLE_OK
任務完成一切都好
2 CURLE_UNSUPPORTED_PROTOCOL
不支援的協定,由URL的頭部指定
3 CURLE_COULDNT_CONNECT
不能連接配接到remote 主機或者代理
4 CURLE_REMOTE_ACCESS_DENIED
通路被拒絕
5 CURLE_HTTP_RETURNED_ERROR
Http傳回錯誤
6 CURLE_READ_ERROR
讀本地檔案錯誤
示例: 擷取html代碼
編譯gcc get_http.c -o get_http –lcurl
./ get_http www.baidu.com
<a></a>