C++使用libcurl做HttpClient(业务观摩,用C++封装过程式代码,post和get的数据,最好url编码,否则+会变成空格)good
当使用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
- #ifndef __HTTP_CURL_H__
- #define __HTTP_CURL_H__
- #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 "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 name="code" class="cpp"> 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;
- }
- <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNTc4MTM4MzMzZGQF+FxsPex77Sht1ZxPy5wLSXk1lpdzRqG9qS69Ybnkmg==" />
服务器收到的__VIEWSTATE值为
- <br>/wEPDwUJNTc4MTM4MzMzZGQF FxsPex77Sht1ZxPy5wLSXk1lpdzRqG9qS69Ybnkmg==<br>
不知道是不是本来就有这个BUG
C++使用libcurl做HttpClient(业务观摩,用C++封装过程式代码,post和get的数据,最好url编码,否则+会变成空格)good的更多相关文章
- C++使用libcurl做HttpClient 和 curl_easy_setopt
curl_easy_setopt 参数设置 https://curl.haxx.se/libcurl/c/curl_easy_setopt.html 使用libcurl做HttpClient #if ...
- vue各生命周期适合做的业务逻辑
一.实际项目中使用最多的Vue生命周期大概是 created mounted updated 二.各自适合做的业务逻辑 1. created 相当于是页面刚开始加载的状态,此时不能操作实例的 ...
- 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2) ...
- Java HttpClient伪造请求之简易封装满足HTTP以及HTTPS请求
HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 jav ...
- windows下openresty中使用lua做接口转发、二次封装等
需求:根据客户需求,可以在ngx下 通过lua做接口二次封装再次转发给用户或第三方 场景:对返回值有要求的.接口屏蔽字段.或做一些业务上的验证等 1.windows直接下载openresty 解压即可 ...
- .NET应用架构设计—工作单元模式(摆脱过程式代码的重要思想,代替DDD实现轻量级业务)
阅读目录: 1.背景介绍 2.过程式代码的真正困境 3.工作单元模式的简单示例 4.总结 1.背景介绍 一直都在谈论面向对象开发,但是开发企业应用系统时,使用面向对象开发最大的问题就是在于,多个对象之 ...
- httpclient模拟post请求json封装表单数据
好长时间不更博了,主要肚子里没什么好墨水,哈哈.废话不说上代码. public static String httpPostWithJSON(String url) throws Exception ...
- 4.3.6 对象的界定通过编写接口来访问带这类命名结构的表会出问题。如前所述,SQL Server的灵活性不应用作编写错误代码或创建问题对象的借口。 注意在使用Management Studio的脚本工具时,SQL Server会界定所有的对象。这不是因为这么做是必须的,也不是编写代码的最佳方式,而是因为在界定符中封装所有的对象,比编写脚本引擎来查找需要界定的对象更容易。
如前所述,在创建对象时,最好避免使用内嵌的空格或保留字作为对象名,但设计人员可能并没有遵守这个最佳实践原则.例如,我当前使用的数据库中有一个审核表名为Transaction,但是Transaction ...
随机推荐
- Java Queue的使用
Queue的成员函数 add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常 rem ...
- GlobalMemoryStatus 和 GlobalMemoryStatusEx
1.获取系统内存信息有2个api,分别是GlobalMemoryStatus和GlobalMemoryStatusEx.GlobalMemoryStatus函数可以在C语言里直接调用,但是Global ...
- php标准库spl栈SplStack如何使用?
php标准库spl栈SplStack如何使用? 一.总结 php标准库spl栈SplStack介绍.(SplStack类)(各种方法都支持) 1.SplStack类:$stack = new SplS ...
- html5中的dom中的各种节点的层次关系是怎样的
html5中的dom中的各种节点的层次关系是怎样的 一.总结 一句话总结:Node节点是所有节点的基类,所以都继承它的方法 1.dom提供在js中动态修改html标签的作用 比如增加修改标签等,并且是 ...
- html常用样式margin、border怎么使用
html常用样式margin.border怎么使用 一.总结 一句话总结:1.margin:auto配合width才能居中:2.border的三个属性依次是边框宽度,边框样式,边框颜色 1.html中 ...
- 使用Boolean类型同步锁引起异常的分析
原文地址 http://topic.csdn.net/u/20080710/19/f61cb4db-ddff-4457-a26a-4ea578b0cc6c.html?87447500 http://w ...
- 西方教育骗局,终于明白精英和普通人的残酷差别!(该校流传着一个数字——4。即“4小时睡眠、4杯咖啡、GPA4.0”——要想获得满分为4分的成绩,每天只睡4个小时,困了就喝4大杯咖啡)
2018-02-14 00:00英国/私立学校 你不知道的是:西方教育通过一个宽松的过程,偷偷完成了社会分层. 1 “中国学生真是太苦了!”我的同学李女士总是发出这样的感慨. 李女士是我中学同学,在一 ...
- Gini 系数与熵的关系
首先来看二者的基本定义: ⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪H(X)=−∑k=1KpklnpkGini(X)=∑k=1Kpk(1−pk) 将 f(x)=−lnx 在 x=1 处进行一阶泰勒展开(忽略高阶无穷小 ...
- UIPasteboard粘贴板:UIlabel开启复制粘贴功能(一)
首先,因为苹果只放出来了 UITextView,UITextField,webView三个控件的剪贴板,所以一般控件的剪贴板都被禁用了,因此,我们首先要做的就是把这属性放出来,其实就是实现三个简单的方 ...
- Java中如何拼接sql或者其他含有变量语句
本原则是个人感悟(不保证完全正确) 第一条原则,首先将一条完整的字符串写好.(例如是"select * from users where id=(id+1)") 凡是变量都需要在其 ...