zoukankan      html  css  js  c++  java
  • C++使用libcurl做HttpClient

    当使用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.html

    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  

    1. #include "httpclient.h"  
    2. #include "curl/curl.h"  
    3. #include <string>  
    4.   
    5. CHttpClient::CHttpClient(void) :   
    6. m_bDebug(false)  
    7. {  
    8.   
    9. }  
    10.   
    11. CHttpClient::~CHttpClient(void)  
    12. {  
    13.   
    14. }  
    15.   
    16. static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)  
    17. {  
    18.     if(itype == CURLINFO_TEXT)  
    19.     {  
    20.         //printf("[TEXT]%s ", pData);  
    21.     }  
    22.     else if(itype == CURLINFO_HEADER_IN)  
    23.     {  
    24.         printf("[HEADER_IN]%s ", pData);  
    25.     }  
    26.     else if(itype == CURLINFO_HEADER_OUT)  
    27.     {  
    28.         printf("[HEADER_OUT]%s ", pData);  
    29.     }  
    30.     else if(itype == CURLINFO_DATA_IN)  
    31.     {  
    32.         printf("[DATA_IN]%s ", pData);  
    33.     }  
    34.     else if(itype == CURLINFO_DATA_OUT)  
    35.     {  
    36.         printf("[DATA_OUT]%s ", pData);  
    37.     }  
    38.     return 0;  
    39. }  
    40.   
    41. static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)  
    42. {  
    43.     std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);  
    44.     if( NULL == str || NULL == buffer )  
    45.     {  
    46.         return -1;  
    47.     }  
    48.   
    49.     char* pData = (char*)buffer;  
    50.     str->append(pData, size * nmemb);  
    51.     return nmemb;  
    52. }  
    53.   
    54. int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse)  
    55. {  
    56.     CURLcode res;  
    57.     CURL* curl = curl_easy_init();  
    58.     if(NULL == curl)  
    59.     {  
    60.         return CURLE_FAILED_INIT;  
    61.     }  
    62.     if(m_bDebug)  
    63.     {  
    64.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
    65.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    66.     }  
    67.     curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    68.     curl_easy_setopt(curl, CURLOPT_POST, 1);  
    69.     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
    70.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    71.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    72.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    73.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    74.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    75.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    76.     res = curl_easy_perform(curl);  
    77.     curl_easy_cleanup(curl);  
    78.     return res;  
    79. }  
    80.   
    81. int CHttpClient::Get(const std::string & strUrl, std::string & strResponse)  
    82. {  
    83.     CURLcode res;  
    84.     CURL* curl = curl_easy_init();  
    85.     if(NULL == curl)  
    86.     {  
    87.         return CURLE_FAILED_INIT;  
    88.     }  
    89.     if(m_bDebug)  
    90.     {  
    91.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
    92.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    93.     }  
    94. <pre name="code" class="cpp">   curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    95.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    96.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    97.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    98.     /** 
    99.     * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。 
    100.     * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。 
    101.     */  
    102.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    103.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    104.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    105.     res = curl_easy_perform(curl);  
    106.     curl_easy_cleanup(curl);  
    107.     return res;  
    108. }  
    109.   
    110. int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)  
    111. {  
    112.     CURLcode res;  
    113.     CURL* curl = curl_easy_init();  
    114.     if(NULL == curl)  
    115.     {  
    116.         return CURLE_FAILED_INIT;  
    117.     }  
    118.     if(m_bDebug)  
    119.     {  
    120.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
    121.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    122.     }  
    123.     curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    124.     curl_easy_setopt(curl, CURLOPT_POST, 1);  
    125.     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
    126.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    127.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    128.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    129.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    130.     if(NULL == pCaPath)  
    131.     {  
    132.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  
    133.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  
    134.     }  
    135.     else  
    136.     {  
    137.         //缺省情况就是PEM,所以无需设置,另外支持DER  
    138.         //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");  
    139.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  
    140.         curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  
    141.     }  
    142.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    143.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    144.     res = curl_easy_perform(curl);  
    145.     curl_easy_cleanup(curl);  
    146.     return res;  
    147. }  
    148.   
    149. int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)  
    150. {  
    151.     CURLcode res;  
    152.     CURL* curl = curl_easy_init();  
    153.     if(NULL == curl)  
    154.     {  
    155.         return CURLE_FAILED_INIT;  
    156.     }  
    157.     if(m_bDebug)  
    158.     {  
    159.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
    160.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    161.     }  
    162.     curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    163.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    164.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    165.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    166.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    167.     if(NULL == pCaPath)  
    168.     {  
    169.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  
    170.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  
    171.     }  
    172.     else  
    173.     {  
    174.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  
    175.         curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  
    176.     }  
    177.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    178.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    179.     res = curl_easy_perform(curl);  
    180.     curl_easy_cleanup(curl);  
    181.     return res;  
    182. }  
    183.   
    184. ///////////////////////////////////////////////////////////////////////////////////////////////  
    185.   
    186. void CHttpClient::SetDebug(bool bDebug)  
    187. {  
    188.     m_bDebug = bDebug;  
    189. }  
    190. </pre><p></p>  
    191. <pre></pre>  
    192. <br>  
    193. <br>  
    194. <p></p>  
    195. <br>  
    196.       
    197.         <div style="padding-top:20px">           
    198.             <p style="font-size:12px;">版权声明:本文为博主原创文章,未经博主允许不得转载。</p>  
    199.         </div>  
  • 相关阅读:
    java生成json字符串的方法
    JSON的三种解析方式
    Android Studio你不知道的调试技巧
    Android 打开URL
    build.gradle中引入jar
    Spark RDD/Core 编程 API入门系列之map、filter、textFile、cache、对Job输出结果进行升和降序、union、groupByKey、join、reduce、lookup(一)
    NovaMind *的安装、和谐破解到永久使用
    小Q书桌的下载、安装和使用
    作业提交过程分析(源码)
    SparkContext的初始化过程分析(源码)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318032.html
Copyright © 2011-2022 走看看