热门标签 | 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;}
 
 



推荐阅读
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 优化局域网SSH连接延迟问题的解决方案
    本文介绍了解决局域网内SSH连接到服务器时出现长时间等待问题的方法。通过调整配置和优化网络设置,可以显著缩短SSH连接的时间。 ... [详细]
  • CentOS 7.6环境下Prometheus与Grafana的集成部署指南
    本文旨在提供一套详细的步骤,指导读者如何在CentOS 7.6操作系统上成功安装和配置Prometheus 2.17.1及Grafana 6.7.2-1,实现高效的数据监控与可视化。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 解决网站乱码问题的综合指南
    本文总结了导致网站乱码的常见原因,并提供了详细的解决方案,包括文件编码、HTML元标签设置、服务器响应头配置、数据库字符集调整以及PHP与MySQL交互时的编码处理。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
  • 本文探讨了高质量C/C++编程的最佳实践,并详细分析了常见的内存错误及其解决方案。通过深入理解内存管理和故障排除技巧,开发者可以编写更健壮的程序。 ... [详细]
  • 通过Web界面管理Linux日志的解决方案
    本指南介绍了一种利用rsyslog、MariaDB和LogAnalyzer搭建集中式日志管理平台的方法,使用户可以通过Web界面查看和分析Linux系统的日志记录。此方案不仅适用于服务器环境,还提供了详细的步骤来确保系统的稳定性和安全性。 ... [详细]
  • CentOS系统安装与配置常见问题及解决方案
    本文详细介绍了在CentOS系统安装过程中遇到的常见问题及其解决方案,包括Vi编辑器的操作、图形界面的安装、网络连接故障排除等。通过本文,读者可以更好地理解和解决这些常见问题。 ... [详细]
  • 阿里云ecs怎么配置php环境,阿里云ecs配置选择 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 本文详细介绍了如何在Kendo UI for jQuery的数据管理组件中,将行标题字段呈现为锚点(即可点击链接),帮助开发人员更高效地实现这一功能。通过具体的代码示例和解释,即使是新手也能轻松掌握。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • Symfony是一个功能强大的PHP框架,以其依赖注入(DI)特性著称。许多流行的PHP框架如Drupal和Laravel的核心组件都基于Symfony构建。本文将详细介绍Symfony的安装方法及其基本使用。 ... [详细]
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社区 版权所有