1、最新libcurl靜態編譯教程(curl-7.51版/curl-7.52版)
一、安裝perl,在官網下載,安裝好之後,測試perl -v是否成功html
二、編譯openssl(已編譯好的下載地址)ios
perl Configure VC-WIN32 --prefix=D:\opensslwindows
ms\do_ms.bat安全
nmake -f ms\nt.mak(靜態編譯)服務器
nmake -f ms\nt.mak installcookie
三、下載libcurl(已編譯好的7.51版下載地址 7.52版下載地址)網絡
在源碼的projects中能夠找到vc14這個項目文件,打開便可。app
而後查看項目的openssl的inc32目錄的路徑在哪裏,能夠看到../../../../../openssl/inc32,因此openssl和libcurl是出於同級目錄的。curl
接着添加openssl中的lib目錄下的libeasy32和ssleay32這2個靜態庫到依賴項中。異步
設置下你要編譯的項目的MTD仍是MT,而後就能夠編譯了。
固然也能夠下載我編譯好的,在上面的地址中。
四、這裏有一份高手進一步封裝的類,很是好用(下載地址)
支持同步和異步請求。
2、簡單使用教程
一、添加包含目錄:libcurl中的include
二、添加庫目錄:libcurl中的lib目錄
三、添加預編譯宏:USE_OPENSSL,CURL_STATICLIB
四、添加庫文件:
crypt32.lib
ws2_32.lib
wldap32.lib
libcurl.lib
五、訪問12306網站,輕鬆繞過https加密的例子:
- #include "stdafx.h"
- #include <stdio.h>
- #include <windows.h>
- #include <iostream>
- #include <string>
- #include <curl/curl.h>
- using namespace std;
-
- size_t Reply(void * ptr, size_t size, size_t nmemb, void * stream)
- {
- string* str = (string*)stream;
- (*str).append((char*)ptr, size*nmemb);
- return size*nmemb;
- }
- wstring str_cvt(const string& from_str, int cvt_type) {
- int wstr_len = MultiByteToWideChar(cvt_type, 0, from_str.c_str(), -1, nullptr, 0);
- wchar_t *wstr = new wchar_t[wstr_len + 1];
- memset(wstr, 0, (wstr_len + 1)*sizeof(wchar_t));
- MultiByteToWideChar(cvt_type, 0, from_str.c_str(), -1, wstr, wstr_len);
- wstring ret_str(wstr); delete[] wstr;
- return ret_str;
- }
- string str_cvt(const wstring& from_str, int cvt_type) {
- int str_len = WideCharToMultiByte(cvt_type, 0, from_str.c_str(), -1, nullptr, 0, nullptr, nullptr);
- char *str = new char[str_len + 1];
- memset(str, 0, str_len + 1);
- WideCharToMultiByte(cvt_type, 0, from_str.c_str(), -1, str, str_len, nullptr, nullptr);
- string ret_str(str); delete[] str;
- return ret_str;
- }
-
- int main()
- {
- string data;
- CURL *curl;
- CURLcode res;
-
- curl_global_init(CURL_GLOBAL_ALL);
-
- curl = curl_easy_init();
- if (curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "https://kyfw.12306.cn/otn/login/init");
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Reply);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
- res = curl_easy_perform(curl);
- if (res != CURLE_OK)
- fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
- curl_easy_cleanup(curl);
- }
- curl_global_cleanup();
- cout << str_cvt(str_cvt(data,CP_UTF8),CP_ACP) << endl;
- getchar();
- return 0;
- }
4、參數詳解:
一、全局環境初始化
- curl_global_init(CURL_GLOBAL_ALL);
- curl_global_cleanup();
CURL_GLOBAL_ALL 初始化全部可能的值,通常用這個宏
CURL_GLOBAL_WIN32 初始化winsock庫
CURL_GLOBAL_SSL 初始化與ssl相關的環境
二、初始化curl
- CURL *curl = curl_easy_init();
- curl_easy_cleanup(curl);
初始化,獲取一個curl對象,無參函數
三、很是重要的函數,設置curl的配置信息
- CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)
a、設置url:
防止30一、302跳轉:
- curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,0);
請求的地址:
- curl_easy_setopt(curl, CURLOPT_URL, "http://www.baidu.com");
b、設置post:
- curl_easy_setopt(curl, CURLOPT_POST, 1);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=xxx");
c、設置coockie
- curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "D:/coockie.txt");
d、設置數據接受
- curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, ShowHtml);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &retStr);
e、設置進度條
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
- curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress);
f、設置ssl忽略驗證
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
g、設置頭信息接受
返回的正文是否有頭信息: curl_easy_setopt(curl, CURLOPT_HEADER, 1);表示有
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, ShowHtml);
- curl_easy_setopt(curl, CURLOPT_HEADERDATA, &retStr);
h、設置上傳
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, ShowHtml);
- curl_easy_setopt(curl, CURLOPT_READDATA, &retStr);
i、設置傳輸時間
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);
j、設置請求頭信息
默認頭信息:
Host:http1.1(大部分http1.0)版本都要求客戶端請求提供這個信息頭。
Pragma:"no-cache"。表示不要緩衝數據。
Accept:"*/*"。表示容許接收任何類型的數據。
Expect: 以POST的方式向HTTP服務器提交請求時,libcurl會設置該消息頭爲"100-continue",它要求服務器在正式處理該請求以前,返回一 個"OK"消息。若是POST的數據很小,libcurl可能不會設置該消息頭
- struct curl_slist *headers = NULL;
- headers = curl_slist_append(headers, "Hey-server-hey: how are you?");
- headers = curl_slist_append(headers, "X-silly-content: yes");
-
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
-
- curl_slist_free_all(headers);
四、獲取應答頭信息
- CURLINFO info;
- curl_easy_getinfo(curl, info);
能夠獲取info中的
- CURLINFO_RESPONSE_CODE
- CURLINFO_HEADER_SIZE
- CURLINFO_COOKIELIST
五、執行查詢操做
- res = curl_easy_perform(curl);
- if (res != CURLE_OK)
- fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
返回值類型有:
- CURLE_OK
- CURLE_UNSUPPORTED_PROTOCOL
- CURLE_COULDNT_CONNECT
- CURLE_REMOTE_ACCESS_DENIED
- CURLE_HTTP_RETURNED_ERROR
- CURLE_READ_ERROR
六、斷點續傳問題
- curl_easy_setopt(curl, CURLOPT_RANGE, 0 - 499, 1000 - 1499);
- curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 1500);
curl_easy_setopt參數大全:
- CURLOPT_HEADER:設爲1,則在返回的內容裏包含http header;
- CURLOPT_FOLLOWLOCATION:設爲0,則不會自動301,302跳轉;
-
- *CURLOPT_INFILESIZE: 當你上傳一個文件到遠程站點,這個選項告訴PHP你上傳文件的大小。
- *CURLOPT_VERBOSE: 若是你想CURL報告每一件意外的事情,設置這個選項爲一個非零值。
- *CURLOPT_HEADER: 若是你想把一個頭包含在輸出中,設置這個選項爲一個非零值。
- *CURLOPT_NOPROGRESS: 若是你不會PHP爲CURL傳輸顯示一個進程條,設置這個選項爲一個非零值。
-
- 注意:PHP自動設置這個選項爲非零值,你應該僅僅爲了調試的目的來改變這個選項。
-
- *CURLOPT_NOBODY: 若是你不想在輸出中包含body部分,設置這個選項爲一個非零值。
- *CURLOPT_FAILONERROR: 若是你想讓PHP在發生錯誤(HTTP代碼返回大於等於300)時,不顯示,設置這個選項爲一人非零值。默認行爲是返回一個正常頁,忽略代碼。
- *CURLOPT_UPLOAD: 若是你想讓PHP爲上傳作準備,設置這個選項爲一個非零值。
- *CURLOPT_POST: 若是你想PHP去作一個正規的HTTP POST,設置這個選項爲一個非零值。這個POST是普通的 application/x-www-from-urlencoded 類型,多數被HTML表單使用。
- *CURLOPT_FTPLISTONLY: 設置這個選項爲非零值,PHP將列出FTP的目錄名列表。
- *CURLOPT_FTPAPPEND: 設置這個選項爲一個非零值,PHP將應用遠程文件代替覆蓋它。
- *CURLOPT_NETRC: 設置這個選項爲一個非零值,PHP將在你的 ~./netrc 文件中查找你要創建鏈接的遠程站點的用戶名及密碼。
- *CURLOPT_FOLLOWLOCATION: 設置這個選項爲一個非零值(象 「Location: 「)的頭,服務器會把它當作HTTP頭的一部分發送(注意這是遞歸的,PHP將發送形如 「Location: 「的頭)。
- *CURLOPT_PUT: 設置這個選項爲一個非零值去用HTTP上傳一個文件。要上傳這個文件必須設置CURLOPT_INFILE和CURLOPT_INFILESIZE選項.
- *CURLOPT_MUTE: 設置這個選項爲一個非零值,PHP對於CURL函數將徹底沉默。
- *CURLOPT_TIMEOUT: 設置一個長整形數,做爲最大延續多少秒。
- *CURLOPT_LOW_SPEED_LIMIT: 設置一個長整形數,控制傳送多少字節。
- *CURLOPT_LOW_SPEED_TIME: 設置一個長整形數,控制多少秒傳送CURLOPT_LOW_SPEED_LIMIT規定的字節數。
- *CURLOPT_RESUME_FROM: 傳遞一個包含字節偏移地址的長整形參數,(你想轉移到的開始表單)。
- *CURLOPT_SSLVERSION: 傳遞一個包含SSL版本的長參數。默認PHP將被它本身努力的肯定,在更多的安全中你必須手工設置。
- *CURLOPT_TIMECONDITION: 傳遞一個長參數,指定怎麼處理CURLOPT_TIMEVALUE參數。你能夠設置這個參數爲TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。這僅用於HTTP。
- *CURLOPT_TIMEVALUE: 傳遞一個從1970-1-1開始到如今的秒數。這個時間將被CURLOPT_TIMEVALUE選項做爲指定值使用,或被默認TIMECOND_IFMODSINCE使用。
-
- 下列選項的值將被做爲字符串:
-
- *CURLOPT_URL: 這是你想用PHP取回的URL地址。你也能夠在用curl_init()函數初始化時設置這個選項。
- *CURLOPT_USERPWD: 傳遞一個形如[username]:[password]風格的字符串,做用PHP去鏈接。
- *CURLOPT_PROXYUSERPWD: 傳遞一個形如[username]:[password] 格式的字符串去鏈接HTTP代理。
- *CURLOPT_RANGE: 傳遞一個你想指定的範圍。它應該是」X-Y」格式,X或Y是被除外的。HTTP傳送一樣支持幾個間隔,用逗句來分隔(X-Y,N-M)。
- *CURLOPT_POSTFIELDS: 傳遞一個做爲HTTP 「POST」操做的全部數據的字符串。
- *CURLOPT_REFERER: 在HTTP請求中包含一個」referer」頭的字符串。
- *CURLOPT_USERAGENT: 在HTTP請求中包含一個」user-agent」頭的字符串。
- *CURLOPT_FTPPORT: 傳遞一個包含被ftp 「POST」指令使用的IP地址。這個POST指令告訴遠程服務器去鏈接咱們指定的IP地址。這個字符串能夠是一個IP地址,一個主機名,一個網絡界面名(在UNIX下),或是‘-’(使用系統默認IP地址)。
- *CURLOPT_COOKIE: 傳遞一個包含HTTP cookie的頭鏈接。
- *CURLOPT_SSLCERT: 傳遞一個包含PEM格式證書的字符串。
- *CURLOPT_SSLCERTPASSWD: 傳遞一個包含使用CURLOPT_SSLCERT證書必需的密碼。
- *CURLOPT_COOKIEFILE: 傳遞一個包含cookie數據的文件的名字的字符串。這個cookie文件能夠是Netscape格式,或是堆存在文件中的HTTP風格的頭。
- *CURLOPT_CUSTOMREQUEST: 當進行HTTP請求時,傳遞一個字符被GET或HEAD使用。爲進行DELETE或其它操做是有益的,更Pass a string to be used instead of GET or HEAD when doing an HTTP request. This is useful for doing or another, more obscure, HTTP request.
-
- 注意: 在確認你的服務器支持命令先不要去這樣作。
-
- 下列的選項要求一個文件描述(經過使用fopen()函數得到):
-
- *CURLOPT_FILE: 這個文件將是你放置傳送的輸出文件,默認是STDOUT.
- *CURLOPT_INFILE: 這個文件是你傳送過來的輸入文件。
- *CURLOPT_WRITEHEADER: 這個文件寫有你輸出的頭部分。
- *CURLOPT_STDERR: 這個文件寫有錯誤而不是stderr。
一個簡單的例子:用來獲取頁面,並顯示獲取進度的例子
- void CcurlTest1Dlg::OnBnClickedOk()
- {
- CURL *curl;
- CURLcode res;
- CStringA retStr;
- CString url;
- GetDlgItemText(IDC_EDIT2,url);
- CProgressCtrl* progress = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
-
- curl_global_init(CURL_GLOBAL_ALL);
- curl = curl_easy_init();
- if (curl) {
- curl_easy_setopt(curl, CURLOPT_URL, UnicodeToAscii(url.GetBuffer(0)).c_str());
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ShowHtml);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &retStr);
- curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
- curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress);
-
- res = curl_easy_perform(curl);
- if (res != CURLE_OK)
- fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
- curl_easy_cleanup(curl);
- }
- curl_global_cleanup();
-
- SetDlgItemTextW(IDC_EDIT1, Utf8ToUnicode(retStr.GetBuffer()).c_str());
- }
- size_t CcurlTest1Dlg::ShowHtml(void * ptr, size_t size,
- size_t nmemb, void * stream)
- {
- int return_size = size*nmemb;
- CStringA* str = (CStringA*)stream;
- *str += (char*)ptr;
- Sleep(500);
- return return_size;
- }
- size_t CcurlTest1Dlg::progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
- {
- CProgressCtrl* progress = (CProgressCtrl*)clientp;
- progress->SetPos(dlnow *100/ dltotal);
- return false;
- }
http://blog.csdn.net/wyansai/article/details/51241594