HTTP/HTTPS客户端源码示例
HTTP/HTTPS客户端源码示例
环境: zlib-1.2.8 openssl-1.0.1g curl-7.36
Author: Kagula
LastUpdateDate: 2014-04
阅读前提:CMake工具的基本使用、配置openssl-1.0.1g 开发环境
编译zlib库
下载zlib-1.2.8.tar.gz并解压缩到" D:\SDK\zlib-1.2.8",使用CMake工具生成zlib.sln,在Visual Studio2013中打开并编译即可。
编译curl-7.36.0
假设Open SSL已经安装到“D:\SDK\openssl-1.0.1g”,先设置下面的环境变量
OPENSSL_LIBRARIES=D:\SDK\openssl-1.0.1g\out32
OPENSSL_ROOT_DIR=D:\SDK\openssl-1.0.1g
从http://curl.haxx.se/下载curl-7.36.0.zip并解压缩到“D:\SDK\curl-7.36.0”启动CMake工具Configure,分别设置LIB_EAY_RELEASE和SSL_EAY_RELEASE变量为“D:\SDK\openssl-1.0.1g\out32\libeay32.lib”,“D:\SDK\openssl-1.0.1g\out32\ssleay32.lib”,产生sln文件后打开,为里面的curl工程项目添加“USE_MANUAL”宏定义,然后build里面的4个项目成功。
为项目添加链接库libcurl_imp.lib , 把libcurl.dll文件复制到C++项目路径下,否则程序运行会提示找不到动态链接库。
下面是HTTP/HTTPS客户端示例
Source.cpp如何调用的示例
#include <iostream> using namespace std; #include "HttpClient.h" //下面是测试代码 using namespace kagula::network; void TestHttpClient() { CHttpClient client; string url; string post; string cookie="d:\\temp\\temp.txt"; string response; url = "http://www.mydrivers.com"; client.Get(url, response); cout << response << endl;; client.Post(url,post,cookie,response); cout << response << endl; url = "https://www.google.com.hk/"; client.GetS(url, response, NULL); cout << response << endl; client.PostS(url, post, cookie, response, NULL); cout << response << endl; } int main(int argc, char *argv[]) { TestHttpClient(); return 0; }
HttpClient.h封装好的头文件
//HttpClient.h源代码清单 #ifndef _HTTPCLIENT_H_ #define _HTTPCLIENT_H_ #include <string> /* 标题:从HTTP/HTTPS服务器中获取页面 测试环境:Windows 8.1 Visual Studio 2013 SP1 libcurl 7.36.0 说明:转自csdn某个页面,对源代码做了小修改,添加了Cookie的支持 参考资料: 《curl_eay_setopt手册》 http://www.helplib.net/s/linux.die/65_2740/man-3-curl-easy-setopt.shtml 《C++的cout高阶格式化操作》 http://www.cnblogs.com/devymex/archive/2010/09/06/1818754.html */ namespace kagula { namespace network { class CHttpClient { public: CHttpClient(void); ~CHttpClient(void); public: /** * @brief HTTP POST请求 * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&… * @param strCookie 输入参数,Cookie文件名,例如 d:\temp\cookie.txt * 如果为空,不启用Cookie. * @param strResponse 输出参数,返回的内容 * @return 返回是否Post成功 */ int Post(const std::string & strUrl, const std::string & strPost, const std::string& strCookie, std::string & strResponse); /** * @brief HTTP GET请求 * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com * @param strResponse 输出参数,返回的内容 * @return 返回是否Post成功 */ int Get(const std::string & strUrl, std::string & strResponse); /** * @brief HTTPS POST请求,无证书版本 * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&… * @param strCookie 输入参数,Cookie文件名,例如 d:\temp\cookie.txt * 如果为空,不启用Cookie. * @param strResponse 输出参数,返回的内容 * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. * @return 返回是否Post成功 */ int PostS(const std::string & strUrl, const std::string & strPost, const std::string& strCookie, std::string & strResponse, const char * pCaPath = NULL); /** * @brief HTTPS GET请求,无证书版本 * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com * @param strResponse 输出参数,返回的内容 * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. * @return 返回是否Post成功 */ int GetS(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL); public: void SetDebug(bool bDebug); private: bool m_bDebug; bool PrintCookies(void* curl,std::string& strOut); }; } } #endif
HttpClient.cpp
//HttpClient.cpp源代码清单 #include "HttpClient.h" #include <iostream> #include <curl/curl.h> #include <iomanip> #include <sstream> namespace kagula { namespace network { CHttpClient::CHttpClient(void) : m_bDebug(false) { } CHttpClient::~CHttpClient(void) { } bool CHttpClient::PrintCookies(void* curl, std::string& strOut) { std::ostringstream ostr; CURLcode res; struct curl_slist *cookies; res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); if (res != CURLE_OK) { ostr << "Curl curl_easy_getinfo failed:" << curl_easy_strerror(res) << std::endl; strOut = ostr.str(); return false; } const struct curl_slist *nc = cookies; int i = 1; ostr << "Cookies, curl knows:" << std::endl; while (nc) { ostr << "[" << i++ << "]: " << nc->data << std::endl; nc = nc->next; } return true; } 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 = reinterpret_cast<std::string*>(lpVoid); if (NULL == str || NULL == buffer) { return -1; } char* pData = reinterpret_cast<char*>(buffer); str->append(pData, size * nmemb); return nmemb; } int CHttpClient::Post(const std::string& strUrl, const std::string& strPost, const std::string& strCookie, 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); if (strCookie.length()>0) { curl_easy_setopt(curl, CURLOPT_COOKIEFILE, (void *)&strCookie); curl_easy_setopt(curl, CURLOPT_COOKIEJAR, (void *)&strCookie); } 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); } 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, const std::string& strCookie, 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 (strCookie.length()>0) { curl_easy_setopt(curl, CURLOPT_COOKIEFILE, (void *)&strCookie); curl_easy_setopt(curl, CURLOPT_COOKIEJAR, (void *)&strCookie); } 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; } } }
补充阅读资料
使用libcurl实现上传文件到FTP服务器
http://blog.csdn.net/lee353086/article/details/5823145
使用libcurl下载http://www.baidu.com/img/baidu.gif示例
http://www.cppblog.com/qiujian5628/archive/2008/06/28/54873.html
libcurl的使用总结(一)
http://www.vimer.cn/2010/03/libcurl%E7%9A%84%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93%EF%BC%88%E4%B8%80%EF%BC%89.html
PHP的curl实现get,post 和 cookie
http://www.tsingpost.com/articles/201403/525.html
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。