---恢復內容開始---
libcurl是一個跨平台的網絡協議庫,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 協議。libcurl同樣支持HTTPS證書授權,HTTP POST, HTTP PUT, FTP 上傳, HTTP基本表單上傳,代理,cookies,和用戶認證。
win32版的libcurl下載地址:
http://curl.freeby.pctools.cl/download/libcurl-7.18.0-win32-msvc.zip
在基於LibCurl的程序里,主要采用callback function (回調函數)的形式完成傳輸任務,用戶在啟動傳輸前設置好各類參數和回調函數,當滿足條件時libcurl將調用用戶的回調函數實現特定功能。
libcurl主要提供了兩種發送http請求的方式,分別是Easy interface方式和multi interface方式,前者是采用阻塞的方式發送單條數據,后者采用組合的方式可以一次性發送多條數據
一、Easy interface
libcurl的easy interface是最基本的用法,簡要流程為:
1、在主線程中調用curl_global_init(CURL_GLOBAL_ALL)初始化
2、調用curl_easy_init獲取一個句柄;
3、調用curl_easy_setopt函數設置此次傳輸的一些基本參數,如url地址、http頭、cookie信息、發送超時時間等,其中,CURLOPT_URL是必設的選項;
4、設置完成后,調用curl_easy_perform函數發送數據;
5、數據發送完畢后,調用curl_easy_cleanup清空句柄;
6、調用curl_global_cleanup()做清理工作。
二、一些基本的函數
1.CURLcode curl_global_init(long flags);
描述:
這個函數只能用一次。(其實在調用curl_global_cleanup 函數后仍然可再用)
如果這個函數在curl_easy_init函數調用時還沒調用,它講由libcurl庫自動調用,所以多線程下最好主動調用該函數以防止在線程中curl_easy_init時多次調用。
這個函數只能用一次。(其實在調用curl_global_cleanup 函數后仍然可再用)
如果這個函數在curl_easy_init函數調用時還沒調用,它講由libcurl庫自動調用,所以多線程下最好主動調用該函數以防止在線程中curl_easy_init時多次調用。
注意:雖然libcurl是線程安全的,但curl_global_init是不能保證線程安全的,所以不要在每個線程中都調用curl_global_init,應該將該函數的調用放在主線程中。
參數:flags
CURL_GLOBAL_ALL //初始化所有的可能的調用。
CURL_GLOBAL_SSL //初始化支持 安全套接字層。
CURL_GLOBAL_WIN32 //初始化win32套接字庫。
CURL_GLOBAL_NOTHING //沒有額外的初始化
CURL_GLOBAL_ALL //初始化所有的可能的調用。
CURL_GLOBAL_SSL //初始化支持 安全套接字層。
CURL_GLOBAL_WIN32 //初始化win32套接字庫。
CURL_GLOBAL_NOTHING //沒有額外的初始化
2 void curl_global_cleanup(void);
描述:在結束libcurl使用的時候,用來對curl_global_init做的工作清理。類似於close的函數。
注意:雖然libcurl是線程安全的,但curl_global_cleanup是不能保證線程安全的,所以不要在每個線程中都調用curl_global_init,應該將該函數的調用放在主線程中。
3 char *curl_version( );
描述: 打印當前libcurl庫的版本。
4 CURL *curl_easy_init( );
描述:
curl_easy_init用來初始化一個CURL的指針(有些像返回FILE類型的指針一樣). 相應的在調用結束時要用curl_easy_cleanup函數清理.
一般curl_easy_init意味着一個會話的開始. 它會返回一個easy_handle(CURL*對象), 一般都用在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類型的指針.
三、 curl_easy_setopt函數部分選項介紹
該函數是curl中非常重要的函數,curl所有設置都是在該函數中完成的,該函數的設置選項眾多,注意本節的闡述的只是部分常見選項。
1. CURLOPT_URL
設置訪問URL
設置訪問URL
2. CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
static size_t OnWriteFile(void* buffer, size_t size, size_t nmemb, void* lpVoid) { FILE* stream = (FILE *)lpVoid; if (nullptr == stream || nullptr == buffer) { return -1; } size_t nWrite = fwrite(buffer, size, nmemb, stream); return nWrite; } curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteFile); //寫入數據的回調 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)m_file);
如果你沒有通過CURLOPT_WRITEFUNCTION屬性給easy handle設置回調函數,libcurl會提供一個默認的回調函數,它只是簡單的將接收到的數據打印到標准輸出。你也可以通過 CURLOPT_WRITEDATA屬性給默認回調函數傳遞一個已經打開的文件指針,用於將數據輸出到文件里。
3. CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
static size_t OnHeader(void* buffer, size_t size, size_t nmemb, void* lpVoid) { std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid); if (nullptr == str || nullptr == buffer) { return -1; } char* pData = (char*)buffer; str->append(pData, size * nmemb); //str后面追加pData return nmemb; } curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, OnHeader); //寫入接受頭的回調 std::string header; curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header);
4. CURLOPT_READFUNCTION CURLOPT_READDATA curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteFile); // 寫入數據的回調 curl_easy_setopt(curl, CURLOPT_WRITEDATA, ( void *)m_file); // 數據指針傳遞給寫回調
static size_t OnWriteFile(void* buffer, size_t size, size_t nmemb, void* lpVoid)
{
FILE* stream = (FILE *)lpVoid;
if (nullptr == stream || nullptr == buffer)
{
return -1;
}
size_t nWrite = fwrite(buffer, size, nmemb, stream);
return nWrite;
}
5. CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
static size_t OnProgress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { curl_http_downloader* dd = (curl_http_downloader*)clientp; if (dd->m_progress) { dd->m_progress(dltotal,dlnow,ultotal,ulnow); } return 0; };
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); //關閉進度表
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, OnProgress); //過時的回調進度表
curl_easy_setopt(curl, CURLOPT_RESUME_FROM, LocalFilelen);
6. CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由於設置傳輸時間,CURLOPT_CONNECTIONTIMEOUT 設置連接等待時間
7. CURLOPT_FOLLOWLOCATION
設置重定位URL
8. 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,指定你希望開始傳遞的 偏移量。
四、 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
讀本地文件錯誤
要獲取詳細的錯誤描述字符串,可以通過const char *curl_easy_strerror(CURLcode errornum ) 這個函數取得.
---恢復內容結束---