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 ...
 
随机推荐
- iOS开发Quartz2D 三 进度条的应用
			
一:效果如图: 二:代码 #import "ViewController.h" #import "ProgressView.h" @interface View ...
 - runtimeException也是能够捕获的
			
如题, 运行结果: bbb abcdef @Test public void testRuntimeException() { ; try { aaa333(); } catch (Exception ...
 - 用JavaScript和CSS实现“在页面中水平和垂直居中”的时钟
			
思路:实现起来最麻烦的事实上是水平居中和垂直居中,当中垂直居中是最麻烦的. 考虑到浏览器兼容性,网上看了一些资料,发如今页面中垂直居中确实没有什么太好的办法. 于是就採用了position:fixed ...
 - Linux 网络编程系列教程
			
一.基础理论篇 01.网络协议入门 02.LAN.WAN.WLAN.VLAN 和 VPN 的区别 03.IP 地址介绍 04.广播地址介绍 05.无连接和面向连接协议的区别 06.因特网的IP协议是不 ...
 - js进阶 10-10  可见伪类选择器和内容伪类选择器的作用
			
js进阶 10-10 可见伪类选择器和内容伪类选择器的作用 一.总结 一句话总结:分组来描述.内容伪类选择器就是 四个 包含.可见的伪类选择器就是可见和不可见.查找功能,也就是内容伪类选择器非常 ...
 - 【Dijkstra+邻接表求次短路】POJ  Sightseeing  3463
			
Language: Default Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7766 Ac ...
 - Java泛型解析(02):通配符限定
			
Java泛型解析(02):通配符限定 考虑一个这种场景.计算数组中的最大元素. [code01] public class ArrayUtil { public static <T&g ...
 - _Decoder_Interface_init xxxxxx in amrFileCodec.o
			
Undefined symbols for architecture arm64: "_Decoder_Interface_init", referenced from: Deco ...
 - Java数组课后习题
			
package javafirst; import java.util.Arrays; class Show{ public void showArray(int[] arr){ for(int i ...
 - Android Studio官方文档: 如何在你的设备上运行你的程序
			
在实体设备上运行您的应用 设置您的设备,如下所示: 使用一根 USB 电缆将您的设备连接到您的开发机器. 如果您是在 Windows 上开发,可能需要为您的设备安装相应的 USB 驱动程序.如需帮助安 ...