小谈libcurl

libcurl库(C++)快速使用 简介libcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP这些协议,同时支持使用SSL 阅读详情

之前使用socket来进行客户端和服务器的通信,必须自己构造HTTP头,HTTP体,非常麻烦,而且容易出错。后来使用了libcurl,真心觉得这是一个好东西。

下面是一个简单的封装类。

http_client.h

#ifndef __HTTP_CLIENT_H__
#define __HTTP_CLIENT_H__

#include <string>
#include <curl/curl.h>
/*
 *@Author LinuxPhilosopy
 *Date: 2013-04-28
 */
using namespace std;
class HttpClient
{
        public:
                HttpClient();
                ~HttpClient();
                /*
                 * connect_timeout_ms 连接超时时间,单位ms
                 * timeout 超时时间
                 * retry_times 重试时间
                 * dns_cache_timeout dns缓存时间
                 */
                int init(int connect_timeout_ms,int timeout,int retry_times,int dns_cache_timeout=60);
                /*
                 * function: POST
                 * url 请求的url
                 * data HTTP包体
                 * resp 响应的包体内容
                 * 0 成功 -1 失败
                 */
                int post_data(const string& url,const string& data,string& resp);
                /*
                 * function: GET
                 * url 请求的url
                 * resp 响应
                 * 0 成功 -1 失败
                 */
                int get_data(const string& url,string& resp);
                /*
                 * Debug
                 */
                void set_verbose(const int verbose);
                /*
                 *回调函数
                 */
                static size_t on_write_data(void * buffer, size_t size, size_t nmemb, string & resp);

        private:
                int _connect_timeout_ms;
                int _timeout;
                int _retry_times;
                int _dns_cache_timeout;
                int _verbose;
                CURL* _handler;
};
#endif

http_client.cpp

#include "http_client.h"

HttpClient::HttpClient()
{
}

HttpClient::~HttpClient()
{
        curl_easy_cleanup(_handler);
        curl_global_cleanup();
}

int HttpClient::init(const int connect_timeout_ms,const int timeout, const int retry_times, int dns_cache_timeout)
{
        _connect_timeout_ms=connect_timeout_ms;
        _timeout = _timeout;
        _retry_times = retry_times;
        _dns_cache_timeout = dns_cache_timeout;
        _verbose=0;

        CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
        if (code != CURLE_OK)
        {
            return -1;
        }
        _handler = curl_easy_init();
        if(!_handler)
        {
                return -1;
        }
        return 0;
}

size_t HttpClient::on_write_data(void * buffer, size_t size, size_t nmemb, string & resp)
{
        long len=size*nmemb;
        resp+=(char*)buffer;
        return len;
}

int HttpClient::post_data(const string & url, const string & data, string & resp)
{
        if( _handler)
        {
                 curl_easy_reset(_handler);
        }else
        {
                 _handler= curl_easy_init();
        }
        curl_easy_setopt(_handler,CURLOPT_URL,url.c_str());
        curl_easy_setopt(_handler,CURLOPT_POSTFIELDS,data.c_str());
        curl_easy_setopt(_handler,CURLOPT_POSTFIELDSIZE,data.length());
        curl_easy_setopt(_handler,CURLOPT_TIMEOUT,_timeout);
        curl_easy_setopt(_handler,CURLOPT_CONNECTTIMEOUT_MS,_connect_timeout_ms);
        curl_easy_setopt(_handler,CURLOPT_DNS_CACHE_TIMEOUT,_dns_cache_timeout);
        curl_easy_setopt(_handler,CURLOPT_NOSIGNAL,1);
        curl_easy_setopt(_handler,CURLOPT_WRITEFUNCTION,on_write_data);
        curl_easy_setopt(_handler,CURLOPT_WRITEDATA,&resp);
        if(_verbose==1)
        {
                curl_easy_setopt(_handler,CURLOPT_VERBOSE,1);
        }
        int i=0;
        CURLcode res;
        for(i=0;i<_retry_times;i++){
                res=curl_easy_perform(_handler);
                if( res == CURLE_OK)
                {
                        break;
                }
                resp="";
        }
        if(i==_retry_times)
                return -1;
        return 0;
}

int HttpClient::get_data(const string& url,string& resp)
{
        if( _handler)
        {
                 curl_easy_reset(_handler);
        }else
        {
                _handler= curl_easy_init();
        }
        curl_easy_setopt(_handler,CURLOPT_URL,url.c_str());
        curl_easy_setopt(_handler,CURLOPT_TIMEOUT,_timeout);
        curl_easy_setopt(_handler,CURLOPT_CONNECTTIMEOUT_MS,_connect_timeout_ms);
        curl_easy_setopt(_handler,CURLOPT_DNS_CACHE_TIMEOUT,_dns_cache_timeout);
        curl_easy_setopt(_handler,CURLOPT_NOSIGNAL,1);
        curl_easy_setopt(_handler,CURLOPT_WRITEFUNCTION,on_write_data);
        curl_easy_setopt(_handler,CURLOPT_WRITEDATA,&resp);
        if(_verbose==1)
        {
                curl_easy_setopt(_handler,CURLOPT_VERBOSE,1);
        }
        int i=0;
        CURLcode res;
        for(i=0;i<_retry_times;i++){
                res=curl_easy_perform(_handler);
                if( res == CURLE_OK)
                {
                        break;
                }
                resp="";
        }
        if(i==_retry_times)
                return -1;
        return 0;
}

void HttpClient::set_verbose(int verbose)
{
        if(verbose!=0)
                _verbose=1;
}

下面是测试demo.

main.cpp

#include "http_client.h"
#include <iostream>
using namespace std;

int main(int argc,char** argv)
{
        HttpClient _client;
        if(_client.init(2000,5,3)<0)
        {
                cout<<"init client failed."<<endl;
                return -1;
        }
        _client.set_verbose(1);
        string url="www.baidu.com";
        string resp;
        if(_client.get_data(url,resp)<0)
        {
                cout<<"curl error."<<endl;
                return -1;
        }
        cout<<"GET 响应:\n"<<resp<<endl;

        url="http://js.vnet.cn/ProvinceForDACS/services/ProvinceForDACS?wsdl";
        string data="<?xml version='1.0' encoding='UTF-8'?><soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' soap:encodingStyle='http://www.w3.org/2001/12/soap-encoding' ><soap:Body><dacs:speedUp xmlns:dacs='http://lccss.linkage.com'><spid>11002001</spid><serviceid>1100200199999998</serviceid><authenticator>fYRJhNKy15fEyzDyt/gq065s5PLe0+Yw</authenticator><starttime>1365749347617</starttime><userid>11009499085</userid><clientIP>114.221.84.35</clientIP><time>0</time><port>8999</port></dacs:speedUp></soap:Body></soap:Envelope>";
        resp="";
        if(_client.post_data(url,data,resp)<0)
        {
                cout<<"post curl error."<<endl;
                return -1;
        }
        cout<<"POST 响应:\n"<<resp<<endl;
        return 0;
}

运行结果:


POST请求中,因为这里是向Web Service提交请求,需要包含相应的请求头,数据包才会被服务器端正确解析。具体自己添加请求头,可以使用如下代码

 struct curl_slist* headers=NULL;
 headers=curl_slist_append(headers,"Content-Type:text/xml");
 curl_slist_append(headers,"Accept:text/xml");
 curl_slist_append(headers,"SOAPAction:''");
 curl_easy_setopt(handle,CURLOPT_HTTPHEADER,headers); 

最后记得释放headers

curl_slist_free_all(headers);

所以从这里也看出这个封装类不够灵活,如果需要自定义HTTP HEADERS,可以在get_data,post_data方法中添加个map参数。但是对于一般的需求这个HttpClient应该大体满足了。。。所以就没加上了。。。

最后,需要注意几点:

1.回调函数必须是类的静态成员函数。

2.如果使用到定时器(我们这里设置了连接超时时间和响应超时等),应设置CURLOPT_NOSIGNAL为1,防止如果主线程使用到sleep或wait,程序自动退出。。。

3.该封装类可以指定重试次数,也比较合理

curl 发送HEAD请求时的数据包 现象:curl 发送HEAD请求时会卡主很慢。 原因:curl接收到的内容小于Content-Length时,就会一直等待接收内容,直到超时(默认5分钟)。 立即下载

相关推荐

基于 Python 的 LIF 模型:探索神经元同步与小世界网络

首先,我们定义了一个LIFNeuronself.soma.L = self.soma.diam = 12.6157 # 固定神经元形状self.cm = cm # 电容self.V_rest = V_rest # 静息电位self.V = V_rest # 初始化膜电位在初始化过程中,每个神经元被赋予初始的静息电位,并且其膜电位会在后续的模拟过程中动态变化。

qq_36224726的博客 1426

libcurl自定义header数据信息头

struct curl_slist *headers = NULL; headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "timestamp: 1627041168"); headers = curl_slist_append(headers, "localtime:1627041168"); headers = curl_slist

3009

超详细neo4j安装教程

一、neo4j简介 最近开始学习知识图谱,所以首先想先学习一下neo4j的使用。 Neo4j是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。由于知识图谱中存在大量的关系型信息(实体—关系—实体), 使用结构化数据库进行存储将产生大量的冗余存储信息, 因此将图数据库作为知识图谱的存储容器成为流行的选择。当前较为常用的图数据库主要有 Neo4j 等。 二、neo4j的安装 功能快捷键 撤销:Ctrl/Command + Z 重做:Ctrl/Command + Y 加粗:Ctrl/Co

qq_38335648的博客 9万+

C++ 用libcurl库进行http通讯网络编程

转自 http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html 目录索引: 一、LibCurl基本编程框架 二、一些基本的函数 三、curl_easy_setopt函数部分选项介绍 四、curl_easy_perform 函数说明(error 状态码) 五、libcurl使用的HTTP消息头 六、获

理性的幻想 7313

麦克斯韦电磁场理论

1)从知识先后上说:麦克斯韦方程组为理解光的传播、反射、折射等现象提供了理论基础。不理解基础,怎么能理解上层建筑。2)从如何学懂上说,把基础学习的越牢,越深刻,后续学习上层建筑就会水到渠成一些,不会越学越多疑问。而是越学越少疑问。

weixin_55255438的博客 2825

图神经网络学习笔记-点云数据处理(专题七)

本教程解释了如何利用图神经网络(Graph Neural Networks,GNNs)来处理和训练点云数据。尽管点云默认情况下不具有图结构,但我们可以利用 PyG 的转换工具,将其转化为适合 PyG 所提供的全套 GNN 模型的形式。关键思想是从点云数据中创建一个,通过 GNN 的消息传递机制,从中学习有意义的局部几何结构。这些点的表示可以被用于例如点云分类或分割等任务。

351

c语言 CURLOPT_HTTPHEADER

c语言 CURLOPT_HTTPHEADER

qq_43559669的博客 1162

YOLOv10改进 | 代码逐行解析(三) | YOLO中的Mosaic增强详解(新手入门必读系列)

本文给大家带来的是YOLOv10中的Mosaic增强代码的详解,可能有部分人对于这一部分比较陌生,有的读者可能知道Mosaic增强但是不知道其工作原理,具体来说Mosaic增强就是指我们的数据集中的图片在输入给模型之前的一个处理过程(我们的图片并不是直接就输入给模型了,大家的训练结果中的结果检测图片大家可以看到数据集中多个图片会组合在一起这就是简单的Mosaic增强),下面我就来讲解一下其在YOLOv10中工作原理和代码定义,下面图片为一个Mosaic增强后的图片。​。

Snu77的博客 2077

libcurl需要注意的部分

1.在设置头的时候,需要注意上传文件headers = curl_slist_append(headers, "Content-type:multipart/form-data"); 否则上传失败,这个意思是解析form-data中的body数据;2.在curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);中的 CURLOPT_HTTPHEADER指的...

博客 608

IEC104协议学习专栏内容规划

IEC104协议的编程学习

sixtome 1110

cesium 气象云(体积云)

本文介绍了基于Cesium的气象云渲染技术方案,其核心是通过GPU加速的光线投射算法实现气象云的三维可视化。方案采用分层架构设计:GPU计算层由顶点着色器和片段着色器组成,负责光线投射计算、3D纹理采样和颜色映射;CPU控制层处理数据预处理、纹理创建和参数配置。关键技术包括:顶点着色器计算相机位置和光线方向,片段着色器实现光线步进采样、颜色映射和半透明混合。该方案高效解决了气象数据与地理场景的融合问题,支持云图、温度场等复杂三维气象数据的实时渲染,具有高真实感和良好性能。

God's asylum的博客 1204

C++ 使用LibCurl 写HTML Header

这里写自定义目录标题C++ 使用LibCurl 写HTML Header C++ 使用LibCurl 写HTML Header /* Simple HTTP GET that stores the headers in a separate file */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <curl/curl.h> static size_t w

qq_23935921的博客 354

RK3568 RGA硬件加速详解:图像缩放、旋转、格式转换10倍提速

RGA(Raster Graphics Acceleration)是瑞芯微(Rockchip)芯片系列中的 2D 图形加速引擎,专门用于处理像素级的图像操作。它通过硬件实现常见的图像处理算法,解放 CPU,降低功耗。RGA 是 RK3568 平台上一颗强大的 2D 图形加速引擎,能够:✅10-20 倍性能提升:大幅减少图像处理时间✅降低 CPU 占用:释放 CPU 资源给其他任务✅丰富的功能:缩放、旋转、裁剪、格式转换一应俱全✅易于集成:librga 提供简洁的 C API。

小灰灰的博客 1697

【小沐学C++】libcurl实现HTTP/HTTPS请求

libcurl 是一个免费且易于使用的客户端 URL 传输 库,支持DICT,FILE,FTP,FTPS,GOPHER,GOPHERS,HTTP,HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POPP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB、SMBS、SMTP、SMTPS、TELNET 和 TFTP。

爱看书的小沐 7954

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

文章1:libcurl中发错重传机制

转载请注明出处 http://blog.youkuaiyun.com/yankai0219/article/details/8159351 0.序 1.libcurl与发错重传相关的内容    1)命令行    2)程序中没有专门进行发错重传的参数或函数 2.libcurl如何实现发错重传 3.总结 0.序      本文目的:实现libcurl的发错重

www.keything.net 6186

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

c++利用libcurl获取http网页的 response headers 等信息

安装环境见:http://blog.youkuaiyun.com/chuanyu/article/details/49507669 然后在libcur/docs/examples文件夹中找到  cookie_interface.c文件 新建一个console工程,配置好libcurl环境,将代码copy就行了 这是最后的结果,http头信息都获取到了:

chuanyu的专栏 1万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

libcurl 使用详解

为了具有通用性,将文件的内容读到了fc变量中,fclen是fc的长度。fc也可以是任何其它内容。curl 是 libcurl句柄。演示省略了很多显而易见的步骤。 1. 普通的post请求,这里用curl_easy_escape对fc做了编码 std::string data("req=plain"); data.append("&file="); char *e

zzhongcy的专栏 6631

libcurl简单介绍和使用

1.libcurl简介 libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证 libcurl的官网http://curl.haxx.se/ 库下载https://github.com/curl/curl/releases/tag/curl-7_7..

gangan 2万+

C 语言使用Libcurl /curl 发送数据 (可以设置http header)

1.环境Windows  2.依赖库文件 头文件: &lt;curl.h&gt; lib: libcurl.a libcurl.dll.a dll: libcurl.dll 下载地址:https://curl.haxx.se/windows/ 3.程序 //#define CURL_STATICLIB #include &lt;stdio.h&gt; #include &l...

Do 1万+

curl用法:获取网站的header头及状态码

curl命令最常用的方法是使用参数-I 获取域名或IP的header信息,包括HTTP返回状态码,server类型,文本类型,缓存时间等等;监控web服务时也常用此方法判断web服务是否正常;监控web服务,可以使用curl获取网站的header头,查看返回值是否是200 OK,作为判断web服务正常的一个标准;使用curl -I 可以获取

sayyy的专栏 8053

libcurl 使用方法简介

libcurl 使用方法简介背景简介使用方法1、easy interface使用方法2、multi interface使用方法 背景 最近想做一个简单的HLS拉流程序,HTTP的下载部分觉得采用libcurl来进行比较合适及方便,所以先介绍libcurl的基本用法,然后使用libcurl完成一个简单的下载小程序。 简介 libcurl是一个跨平台的开源网络协议库,支持http, https, rt...

myvest的专栏 4万+

关于curl添加请求头

开始搜索了一下curl怎么添加请求头,都是抄来抄去,用-H添加,但是具体解析的时候会将-H的内容误以为是链接,找不到对应的host,我的版本是7.42.0,后来Google了一下,还是Google靠谱,在Stack Overflow上面看到用--header "data: data" 添加就可以正常添加了,例子:curl --header "Accept-Language: zh-cn" -v w

you_and_dream的博客 5万+

c/c++调用libcurl库发送http请求的两种基本用法

libcurl主要提供了两种发送http请求的方式,分别是Easy interface方式和multi interface方式,前者是采用阻塞的方式发送单条数据,后者采用组合的方式可以一次性发送多条数据 一、Easy interface libcurl的easy interface是最基本的用法,简要流程为: 1、在主线程中调用curl_global_init(CURL_GLOBAL_A

mao834099514的博客 6686

curl命令详解、实例 -- libcurl

linux curl是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称url为下载工具。   一,curl命令参数,有好多我没有用过,也不知道翻译的对不对,如果有误的地方,还请指正。 查看 复制 打印 ? -a/--append 上传文件时,附加到目标文件    -A/--user-agent

《我是你的正能量》 3685
上一篇: Makefile
下一篇: Encoding URLs
蜗niu漫步
博客等级 码龄14年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值