热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C++使用libcurl做HttpClient

当使用C++做HTTP客户端时,目前通用的做法就是使用libcurl。其官方网站的地址是http:curl.haxx.se,该网站主要提供了Curl和libcurl。Curl是命令

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

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 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 *)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;}
 
 



推荐阅读
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • 一、使用Microsoft.Office.Interop.Excel.DLL需要安装Office代码如下:2publicstaticboolExportExcel(S ... [详细]
  • egg实现登录鉴权(七):权限管理
    权限管理包含三部分:访问页面的权限,操作功能的权限和获取数据权限。页面权限:登录用户所属角色的可访问页面的权限功能权限:登录用户所属角色的可访问页面的操作权限数据权限:登录用户所属 ... [详细]
  • C/C++ 应用程序的安装与卸载解决方案
    本文介绍了如何使用Inno Setup来创建C/C++应用程序的安装程序,包括自动检测并安装所需的运行库,确保应用能够顺利安装和卸载。 ... [详细]
  • java类名的作用_java下Class.forName的作用是什么,为什么要使用它?
    湖上湖返回与带有给定字符串名的类或接口相关联的Class对象。调用此方法等效于:Class.forName(className,true,currentLoader) ... [详细]
  • 在Ubuntu 18.04上使用Nginx搭建RTMP流媒体服务器
    本文详细介绍了如何在Ubuntu 18.04上使用Nginx和nginx-rtmp-module模块搭建RTMP流媒体服务器,包括环境搭建、配置文件修改和推流拉流操作。适用于需要搭建流媒体服务器的技术人员。 ... [详细]
  • SDWebImage第三方库学习
    1、基本使用方法异步下载并缓存-(void)sd_setImageWithURL:(nullableNSURL*)urlNS_REFINED_FOR_SWIFT;使用占位图片& ... [详细]
  • mybatis 详解(七)一对一、一对多、多对多
    mybatis详解(七)------一 ... [详细]
  • Spring 中策略模式的应用:Resource 接口详解
    本文探讨了在 Spring 框架中如何利用 Resource 接口实现资源访问策略。Resource 接口作为资源访问策略的抽象,通过多种实现类支持不同类型的资源访问。 ... [详细]
  • 利用爬虫技术抓取数据,结合Fiddler与Postman在Chrome中的应用优化提交流程
    本文探讨了如何利用爬虫技术抓取目标网站的数据,并结合Fiddler和Postman工具在Chrome浏览器中的应用,优化数据提交流程。通过详细的抓包分析和模拟提交,有效提升了数据抓取的效率和准确性。此外,文章还介绍了如何使用这些工具进行调试和优化,为开发者提供了实用的操作指南。 ... [详细]
  • spring boot使用jetty无法启动 ... [详细]
  • 解决JavaScript中法语字符排序问题
    在开发一个使用JavaScript、HTML和CSS的Web应用时,遇到从SQLite数据库中提取的法语词汇排序不正确的问题,特别是带重音符号的字母未按预期排序。 ... [详细]
  • 【实例简介】本文详细介绍了如何在PHP中实现微信支付的退款功能,并提供了订单创建类的完整代码及调用示例。在配置过程中,需确保正确设置相关参数,特别是证书路径应根据项目实际情况进行调整。为了保证系统的安全性,存放证书的目录需要设置为可读权限。值得注意的是,普通支付操作无需证书,但在执行退款操作时必须提供证书。此外,本文还对常见的错误处理和调试技巧进行了说明,帮助开发者快速定位和解决问题。 ... [详细]
  • 在最近的项目中,我们广泛使用了Qt框架的网络库,过程中遇到了一些挑战和问题。本文旨在记录这些经验和解决方案,以便日后参考。鉴于我们的客户端GUI完全基于Qt开发,我们期望利用其强大的网络功能进行Fiddler网络数据包的捕获与分析,以提升开发效率和应用性能。 ... [详细]
author-avatar
一个人的生活啦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有