标签:curl libcurl c++ windows curl库
curl 是一个利用URL语法在命令行方式下工作的文件传输工具。它支持很多协议:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP。curl不但提供了一个可执行的工具库,还提供了供程序开发的libcurl库,该库使用c语言编写,支持跨平台,libcurl的下载地址点这里。下载的安装包里面有个Project文件夹,该目录下全是已经对用户提供的Visual Studio工程库,包括Visual Studio的各个版本,提供代码示例以及库的编译,而且还提供多种编译方式,包括静态库,动态库,调试版、发布版,所谓真是业界良心的。提供的版本列表如下所示:
编译curl库很简单的,找到自己对应的VS目录,然后打开工程,选择所需要的版本即可编译。我使用的是VS2010的静态库版本,因此选择VC10目录->LIB Debug版本,然后编译,编译后生成libcurld.lib和对应的调试信息文件libcurld.pdb,这样我们开发调试的时候只需要把该库文件和curl库的头文件文件夹curl加到我们的工程里面就可以使用curl库给我们提供的功能了。不过需要注意的是,因为CURL的特殊性,需要预定义一些宏和添加特定的依赖库,如下所示:
// 需要定义的宏,要不然会提示找不到某些函数的定义 #define BUILDING_LIBCURL //#define HTTP_ONLY // 依赖库 #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "wldap32.lib") #pragma comment(lib, "libcurld.lib")
CURLcode curl_global_init(long flags);描述: 这个函数只能用一次(其实在调用curl_global_cleanup 函数后仍然可再用),如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动完成。
void curl_global_cleanup(void);描述:在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。
char *curl_version();描述: 打印当前libcurl库的版本。
CURL *curl_easy_init();描述: curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样),相应的在调用结束时要用curl_easy_cleanup函数清理。一般curl_easy_init意味着一个会话的开始,它的返回值一般都用在easy系列的函数。
void curl_easy_cleanup(CURL *handle);描述: 这个调用用来结束一个会话,与curl_easy_init配合着用。
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);描述: 这个函数最重要了,几乎所有的curl程序都要频繁的使用它,用来设置参数。它告诉curl库,程序将有如何的行为,比如要查看一个网页的html代码等。
CURLcode curl_easy_perform(CURL *handle);描述:这个函数在初始化CURL类型的指针以及curl_easy_setopt完成后调用,就像字面的意思所说perform就像是个舞台,让我们设置的option运作起来,执行curl所设置的动作。
一个使用curl封装Post和Get方法的类
#ifndef __MY_CURL_H__ #define __MY_CURL_H__ #define BUILDING_LIBCURL //#define HTTP_ONLY #include <string> 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 strResponse 输出参数,返回的内容 * @return 返回是否Post成功 */ int Post(const std::string & strUrl, const std::string & strPost, 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 strResponse 输出参数,返回的内容 * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. * @return 返回是否Post成功 */ int Posts(const std::string & strUrl, const std::string & strPost, 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; }; #endif
#include "my_curl.h" #include "curl/curl.h" #include <string> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "wldap32.lib") #pragma comment(lib, "libcurld.lib") 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); } 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; }从上述代码可以看出,使用curl库主要分为四个步骤:init,setopt,perform和cleanup,其中setopt最重要,用来指定参数
标签:curl libcurl c++ windows curl库
原文地址:http://blog.csdn.net/arbboter/article/details/43448189