原文來自:http://blog.csdn.net/huyiyang2010/article/details/7664201 轉載請註明html
當使用C++作HTTP客戶端時,目前通用的作法就是使用libcurl。其官方網站的地址是http://curl.haxx.se/,該網站主要提供了Curl和libcurl。Curl是命令行工具,用於完成FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP的命令的請求及接收回饋。libcurl提供給開發者,用於使用C++跨平臺的開發各類網絡協議的請求及響應。裏面的文檔很是齊全,不過都是英文的。服務器
本文提供最簡單的demo使用libcurl開發HttpClient。主要包括同步的HTTP GET、HTTP POST、HTTPS GET、HTTPS POST。網絡
下載libcurl包,若是使用Linux平臺,建議下載源文件編譯;若是使用Windows平臺,建議下載Win32 - MSVC,下載地址是:http://curl.haxx.se/download.htmlapp
1 #ifndef __HTTP_CURL_H__ 2 #define __HTTP_CURL_H__ 3 4 #include <string> 5 6 class CHttpClient 7 { 8 public: 9 CHttpClient(void); 10 ~CHttpClient(void); 11 12 public: 13 /** 14 * @brief HTTP POST請求 15 * @param strUrl 輸入參數,請求的Url地址,如:http://www.baidu.com 16 * @param strPost 輸入參數,使用以下格式para1=val1¶2=val2&… 17 * @param strResponse 輸出參數,返回的內容 18 * @return 返回是否Post成功 19 */ 20 int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse); 21 22 /** 23 * @brief HTTP GET請求 24 * @param strUrl 輸入參數,請求的Url地址,如:http://www.baidu.com 25 * @param strResponse 輸出參數,返回的內容 26 * @return 返回是否Post成功 27 */ 28 int Get(const std::string & strUrl, std::string & strResponse); 29 30 /** 31 * @brief HTTPS POST請求,無證書版本 32 * @param strUrl 輸入參數,請求的Url地址,如:https://www.alipay.com 33 * @param strPost 輸入參數,使用以下格式para1=val1¶2=val2&… 34 * @param strResponse 輸出參數,返回的內容 35 * @param pCaPath 輸入參數,爲CA證書的路徑.若是輸入爲NULL,則不驗證服務器端證書的有效性. 36 * @return 返回是否Post成功 37 */ 38 int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL); 39 40 /** 41 * @brief HTTPS GET請求,無證書版本 42 * @param strUrl 輸入參數,請求的Url地址,如:https://www.alipay.com 43 * @param strResponse 輸出參數,返回的內容 44 * @param pCaPath 輸入參數,爲CA證書的路徑.若是輸入爲NULL,則不驗證服務器端證書的有效性. 45 * @return 返回是否Post成功 46 */ 47 int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL); 48 49 public: 50 void SetDebug(bool bDebug); 51 52 private: 53 bool m_bDebug; 54 }; 55 56 #endif
#include "httpclient.h" #include "curl/curl.h" #include <string> CHttpClient::CHttpClient(void) : m_bDebug(false) { } CHttpClient::~CHttpClient(void) { } static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *) { if(itype == CURLINFO_TEXT) { //printf("[TEXT]%s\n", pData); } else if(itype == CURLINFO_HEADER_IN) { printf("[HEADER_IN]%s\n", pData); } else if(itype == CURLINFO_HEADER_OUT) { printf("[HEADER_OUT]%s\n", pData); } else if(itype == CURLINFO_DATA_IN) { printf("[DATA_IN]%s\n", pData); } else if(itype == CURLINFO_DATA_OUT) { printf("[DATA_OUT]%s\n", pData); } return 0; } static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid) { std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid); if( NULL == str || NULL == buffer ) { return -1; } char* pData = (char*)buffer; str->append(pData, size * nmemb); return nmemb; } int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); res = curl_easy_perform(curl); curl_easy_cleanup(curl); return res; } int CHttpClient::Get(const std::string & strUrl, std::string & strResponse) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } <PRE class=cpp name="code"> curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); /** * 當多個線程都使用超時處理的時候,同時主線程中有sleep或是wait等操做。 * 若是不設置這個選項,libcurl將會發信號打斷這個wait從而致使程序退出。 */ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); res = curl_easy_perform(curl); curl_easy_cleanup(curl); return res; } int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if(NULL == pCaPath) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); } else { //缺省狀況就是PEM,因此無需設置,另外支持DER //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM"); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath); } curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); res = curl_easy_perform(curl); curl_easy_cleanup(curl); return res; } int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath) { CURLcode res; CURL* curl = curl_easy_init(); if(NULL == curl) { return CURLE_FAILED_INIT; } if(m_bDebug) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); } curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); if(NULL == pCaPath) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); } else { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath); } curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); res = curl_easy_perform(curl); curl_easy_cleanup(curl); return res; } /////////////////////////////////////////////////////////////////////////////////////////////// void CHttpClient::SetDebug(bool bDebug) { m_bDebug = bDebug; } </PRE><P></P> <PRE></PRE> <BR> <BR> <P></P> <BR>