记整理–LibCurl开发

LibCurl开发_莫了的冰暴_百度空间 – Google Chrome (2013/7/26 21:11:15)

LibCurl开发

一:LibCurl 编程流程
1.调用curl_global_init()初始化libcurl
2.调用 curl_easy_init()函数得到 easy interface型指针
3.调用curl_easy_setopt设置导选项
4.根据curl_easy_setopt设置的传选项,实现回调函数以形成用户特定任务
5.调用curl_easy_perform()函数完成传输任务
6.调用curl_easy_cleanup()释放内存

仲:重要函数
1、CURLcode curl_global_init(long flags); //初始化libcurl
叙述:这个函数只能用平等次于。(其实以调用curl_global_cleanup 函数后仍旧只是又就此),如果这函数在curl_easy_init函数调用时还从来不调用,它都是因为libcurl库自动完成。
参数:flags
CURL_GLOBAL_ALL              //初始化所有的也许的调用。
CURL_GLOBAL_SSL              //初始化支持 安全法接字层。
CURL_GLOBAL_WIN32            //初始化win32法接字库。
CURL_GLOBAL_NOTHING          //没有额外的初始化。

2、void curl_global_cleanup(void);
叙:在竣工libcurl使用的下,用来针对curl_global_init做的行事清理。类似于close的函数。

3、char *curl_version( );
叙述: 打印当前libcurl库的版本。

4、CURL *curl_easy_init( );  //得到 easy interface型指针
描述:curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样). 相应的以调用了时假如因此curl_easy_cleanup函数清理.
一般curl_easy_init意味着一个会话的开始. 它的返回值一般都为此当easy系列的函数中.
5、void curl_easy_cleanup(CURL *handle); //释放内存
讲述:这个调用用来收场一个会面话.与curl_easy_init配合着用.
参数:CURL类型的指针.

6、CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);  //设置的导选项,实现回调函数以成功用户特定任务
叙: 这个函数最着重了.几乎有的curl 程序还设数的用它.它告curl库.程序将发出哪的表现. 比如使查看一个网页的html代码等.(这个函数有些像ioctl函数)参数:
(1) CURL类型的指针
(2) 各种CURLoption类型的选择项.(都当curl.h库里发出定义,man 也得以翻相)
(3) parameter 这个参数既好是独函数的指针,也可是有对象的指针,也可以是单long型的变量.它用啊这有赖于第二独参数.
(4) CURLoption 这个参数的取值很多.具体的可查阅man手册.

7、CURLcode curl_easy_perform(CURL *handle);  //完成传输任务;返回0意味一切ok,非0代表错误有
讲述:这个函数在初始化CURL类型的指针 以及curl_easy_setopt完成后调用. 就像字面的意所说perform就比如是单舞台.让我们安的option 运作起来.
参数:CURL类型的指针.
补充:
(1)每当连续过程被,如果出现异常,如网线拔掉,返回CURLE_COULDNT_CONNECT;

(2)于下载过程遭到,即已连续达了,后面要出现异常,如网线拔掉,返回CURLE_OPERATION_TIMEOUTED

8、curl_slist_append(struct curl_slist * list, const char * string );   //add a string to an slist
9、curl_slist_free_all(slist); // free the list again

10、curl_formadd(struct curl_httppost ** firstitem, struct curl_httppost ** lastitem, …)  //add a section to a multipart/formdata HTTP POST

11、其它
/****************************************************************/
libcurl note(Http应用)
设置Callback function处理Http头返回内容,进度
CURLOPT_WRITEFUNCTION
CURLOPT_WRITEDATA

CURLOPT_HEADERFUNCTION
CURLOPT_HEADERDATA

CURLOPT_NOPROGRESS
CURLOPT_PROGRESSFUNCTION
CURLOPT_PROGRESSDATA

设置连接等时,传输等时:

CURLOPT_TIMEOUT:
CURLOPT_CONNECTIONTIMEOUT:

安重定位URL:

CURLOPT_FOLLOWLOCATION

贯彻断点续传
CURLOPT_RANGE:
CURLOPT_RESUME_FROM:

CURLOPT_RANGE:
CURLOPT_RESUME_FROM:

流动: 在本人的测试着 这点儿只参数无效。 

安RANGE后 下充斥通数量,而非是累数据;

设置RESUME_FROM后,程序无响应。

Http头设置:
Range: bytes=xx-       [可为此来促成断点续传]
User-Agent: xx
Location:              [网页又一贯 url]
Set-Cookie:            [Cookie]
Content-Length:        [报文长度]
Content-Type:            [报文类型]
/****************************************************************/

老三:应用实例
1、为什么而动libcurl,
(1)作为http的客户端,可以一直用socket连接服务器,然后针对顶之多少开展http解析,但倘若分析协议头,实现代理…这样太难为了。
(2)libcurl是一个开源的客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP,支持Windows,Unix,Linux等楼台,简单好用,且库文件占用空间不顶200K。

2、get和post方式
客户端在http连接时向劳动付出数据的不二法门分为get和post两栽
(1)Get方式拿所要传的多少附在网址后,然后一并送达服务器,它的长处是效率比较高;缺点是安全性差、数据不超越1024只字符、必须是7员之ASCII编码;查询时经常用之方式。
(2)Post通过Http post处理发送数据,它的长处是安全性比较强、支持数据量大、支持字符多;缺点是效率相对低位;编辑修改时大都使用这个措施。

3、cookie与session
(1)cookie是出殡到客户浏览器的公文串句柄,并保存在客户机硬盘上,可以据此来在某Web站点会话之间持久地保持数据。cookie在客户端。
(2)session是访问者从抵达某特定主页到离为止的那段时光。每一样访问者都见面独自赢得一个session,实现站点多个用户中在备页面中共享信息。session在服务器上。
(3)libcurl中利用cookie,保存cookie, 使之后的链接和是链接以同一的cookie
(3.1)在关门链接的时把cookie写副指定的公文:  curl_easy_setopt(curl, CURLOPT_COOKIEJAR, “/tmp/cookie.txt”);
(3.2)取用现在有cookie,而未又取cookie:  curl_easy_setopt(curl, CURLOPT_COOKIEFILE, “/tmp/cookie.txt”);

4、http与https的区别
(1)Http是公开发送,任何人都足以阻碍并读取内容
(2)Https是加密传输协议,用她传输的情还是加密了的,https是http的壮大,其安根基是SSL协议
5、base64编码
(1)如果要传一模一样段落包含特殊字符比较多之数据,直接上污染就需要处理转意符之类的多题目,于是base64编码,它可以拿数量变动成可读的字串,base64由a-z, A-Z, +/总计64只字符组成。
(2)出于base64的有的来加号,而加号是url中之转意字符,所以无get方式还是post,传到服务器的进程遭到,都见面拿加号转成为空格,所以在传base64之前要将base64编码后底加号替换成”%2B”,这样便可正常发送了。

6、curl_setop()函数中的参数中文说明

curl_setopt()函数将为一个CURL会话设置选项。option参数是你想如果之装置,value是以此选项给定的价。下列选项的价将让看成长整形使用(在option参数中指定)
代码例程

libcurl 以笔记 – 喜欢初美 – 博客大巴 – Google Chrome (2013/7/26 17:50:53)

libcurl 以笔记

日期:2009-12-24 | 分类:c & c++

libcurl 是一个不胜不错的库,支持http,ftp等诸多之商议。使用库太酷之经验就是,不仔细看文档,仅仅看正在例子就是写序,是同码危险的业务。我的顺序崩溃了,我怀疑是协调代码写的题目,后来发觉是堆栈没因此对。不细瞧看文档(有时候文档本身吗于差劲,这时除了看仔细外,还要多动脑子,考虑其是怎么落实之),后果非常惨重。不加思索的使他人的库房或者代码,有时候很乐意,但是来题目经常,却是忐忑不安的。

1. CURLcode curl_global_init(long
flags);
在差不多线程应用被,需要在主线程中调用这个函数。这个函数设置libcurl所需要的环境。通常状态,如果未显式的调用它,第一不行调动用curl_easy_init()时,curl_easy_init
会调用
curl_global_init,在单线程环境下,这不是问题。但是多线程下就可怜了,因为curl_global_init不是线程安全之。在差不多独线程中调用curl_easy_int,然后使少个线程同时发现curl_global_init还从未叫调用,同时调用curl_global_init,悲剧便有了。这种状态时有发生的票房价值很粗,但可能是存的。

  1. libcurl
    有个坏好之特征,它竟然可以决定域名解析的过。但是于默认情况下,它是采用alarm
  2. siglongjmp
    实现之。用alarm在差不多线程下开过,本身就几乎无可能。如果只是利用alarm,并无见面导致程序崩溃,但是,再长siglongjmp,就如命了(程序崩溃的生吓人,core中几看无生有因此信息),因为那个需要一个sigjmp_buf型的全局变量,多线程修改它。(通常状态下,可以每个线程一个
    sigjmp_buf 型的变量,这种状况下,多线程中使用 siglongjmp
    是没有问题之,但是libcurl只生一个全局变量,所有的线程都见面因此)。

  具体是近乎
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L)
的逾期设置,导致alarm的运用(估计有在域名解析阶段),如前所述,这当差不多线程中凡是老的。解决方法是剥夺掉alarm这种跨时,
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L)。

 
这样,多线程中运用过期就高枕无忧了。但是域名解析就没有了过机制,碰到很缓慢的域名解析,也生辛苦。文档的建议是 Consider building libcurl with
c-ares support to enable asynchronous DNS lookups, which enables nice
timeouts for name resolves without signals.  c-ares 是异步的 DNS 解决方案。

收藏到:Del.icio.us

运用 cURL 和 libcurl 通过 Internet 进行对话 – Google Chrome (2013/7/26 16:58:48)

动用 cURL 和 libcurl 通过 Internet 进行对话

拿 libcurl 与 C 以及 Python 结合使用

Tim M. Jones,
顾问工程师,  

简介: cURL 是一个命令行工具,可以针对文件传输使用多协商,包括
HTTP、FTP、Secure Copy (SCP)、Telnet 等等。但是,除了可以用命令行通过
Internet 与端点对话外,还好采用 libcurl
编写简单或复杂的次,以自动化执行应用层的协议任务。本文将介绍 cURL
命令行工具,然后朝您出示如何利用 libcurl 以及 C 和 Python 构建一个 HTTP
客户端。

颁布日期: 2009 年 10 月 29 日 
级别: 初级 
别语言版: 英文 
访情况 : 10620 次浏览 
评论: 0 (查看 | 添加品 – 登录)

图片 1 平均分 (14个评分)
啊本文评分

出 HTTP 和 FTP
之类依赖让应用层协议的应用程序并无复杂,但为无略。进一步说,这不是应用程序的基本点,因为多数场面下,协议之上的情节才是实在要的情。因此,libcurl
引起了成百上千总人口之趣味,因为它们的首要是应用程序而休是支付之各个方面。注意,很少生应用程序开发自己的
TCP/IP
堆栈,所以老话重提:尽可能用以极端小化开发安排并加强应用程序的可靠性。

本文首先简单介绍应用层协议,然后介绍 cURL、libcurl 并分解其的用法。

Web
协议

本构建应用程序已和过去大不相同。现在之应用程序需要能由此网要
Internet 进行报道(提供人类可用之大网 API
或接口),还要能支持用户脚本化以增强灵活性。现代应用程序通常采用 HTTP
公开 Web 接口,并经 Simple Mail Transport Protocol (SMTP)
提供警告通知。这些协议允许而将 Web
浏览器指向设备为赢得配置或者状态信息,并打设备或者常用的电子邮件客户端接收标准电子邮件(分别通过
HTTP 和 SMTP)。

这些 Web 服务普通构建以网堆栈的套接字层上(见图
1)。套接字层实现一个初次出现在 Berkeley Software Distribution (BSD)
操作系统上之 API,并领取底层传输和网络层协议的详细信息。

图 1. 网络堆栈和 libcurl
图片 2 

Web 服务产生在客户端和服务器之间的磋商对话中。在 HTTP
上下文中,服务器是终极设备,客户端是置身端点上之浏览器。对于
SMTP,服务器是邮件网关或端点用户,客户端是终端设备。在一些情况下,协议对话来在片个步骤(请求与响应)中,但其余一些场面下,需要商谈与报道的通信量更多。这种协议或者增加了汪洋苛,这足以经过
API 进行抽象,比如 libcurl。

回页首

cURL
简介

cURL 的根源与提高

cURL 是 Daniel Stenberg 发明的,但是 600
多号称开发人员也做出了赫赫的贡献。它实实在在是群应用程序都用的中技术之一。

cURL 最初的计划性初衷是采用不同的协议(比如 FTP、HTTP、SCP
等)在端点之间活动文件。它最初是一个命令行实用工具,但现啊是一个绑定了
30 多种语言的库。因此,现在不仅仅可通过 shell 使用
cURL,您还可以构建统一了这要功能的应用程序。libcurl
库也是得移植的,支持 Linux®、IBM®AIX®操作系统、BSD、Solaris
以及众多旁 UNIX®变体。

回页首

博与安装
cURL/libcurl

取得和装置 libcurl 非常简单,取决于你所运行的 Linux 发行版。如果运行的凡
Ubuntu,您可采用 apt-get轻松安装这些保险。以下行演示了怎么也
libcurl 安装 libcurl 和 Python 绑定:

 $ sudo apt-get install libcurl3
 $ sudo apt-get install python-pycurl
            

apt-get实用工具确保该过程满足所有的仗关系。

回页首

每当命令行中使用 cURL

cURL 最开始是一个命令行工具,可以应用 Uniform Resource Locator (URL)
语法执行多少传。考虑到其当命令执行及之流行度,后来创设了一个可以在应用程序中生成这些作为之库。如今,命令行
cURL 是 cURL 库的包装器。本文首先研究 cURL
作为命令行的力量,然后深入探讨如何将它们看成仓库使用。

cURL 的一定量种植普遍用法是使用 HTTP 和 FTP 协议进行文件传输。cURL
也这些协议提供一个简短的接口。要运用 HTTP 从网站取得文件,只需要报 cURL
您如果用网页写副到内的本地文件的文本称、网站的 URL
以及一旦收获之文件。让咱们看一下清单 1 中之简练命令行示例。

清单 1. 使 cURL 从网站取得文件之演示

                
 $ curl -o test html www.exampledomain.com
  % Total    % Received % Xferd  Average Speed    Time    Time     Time    Current 
                                 Dload  Upload    Total   Spent    Left    Speed 
 100 43320  100 43320    0     0  55831       0 --:--:-- --:--:-- --:--:--  89299 
 $ 

留意,由于我指定了地区而休是文本,我将收获根文件(index.html)。要动用
cURL 将该公文移动及 FTP 站点,可以行使 -T慎选指定要达成污染之公文,然后提供
FTP 站点的 URL 以及文件之途径。

清单 2. 运 cURL 将文件上传到 FTP 站点的演示

              
 $ curl -T test.html ftp://user:password@ftp.exampledomain.com/ftpdir/
  % Total    % Received % Xferd  Average Speed    Time    Time     Time    Current 
                                 Dload  Upload    Total   Spent    Left    Speed 
 100 43320    0     0  100 43320      0  38946   0:00:01 0:00:01  --:--:--    124k 
 $ 

凡是休是坏简短?学习了一些模式下你会发觉,cURL
以起来非常简单。但是你得运用的选项项好多 —在 cURL
命令行中请求增援(使用 --help)可以落 129
行选项。如果您觉得这尚未到底太多,那么还起一样挺批判其他控制选项(从详细度到安全性),以及特定于协议的配置起。

从今开发人员的角度看,这尚免到底 cURL 最令人兴奋的地方。让咱深入了解
cURL 库,学习怎么为应用程序添加文件传输协议。

回页首

作仓库底 cURL

一经您来 10
年以上的脚本语言经验,您尽管见面注意到它的标志有十分非常之浮动。Python、Ruby、Perl
等这些脚本语言不仅涵盖套接字层(C 或 C++ 中也生),还隐含了应用层协议
API。这些脚本语言合并了尖端功能,可以创造 HTTP 服务器或客户端。libcurl
库为 C 和 C++
之类的语言上加了看似之效能,但是它可以在不同的言语里移植。在装有它支持的语言中还能找到与
libcurl 相当之作为,但是由这些语言的差异大十分(设想一下 C 和
Scheme),提供这些行为之方呢殊无等同。

libcurl 库以 API 的款型封装清单 1和清单 2遭逢讲述的表现,因此它好吃高级语言应用(如今已过
30 栽)。本文提供了 libcurl 的简单个示范。第一单示范研究利用 c 构建的简便
HTTP 客户端(适合构建 Web 爬行器),第二只示范是一个采用 Python
创建的简要 HTTP 客户端。

回页首

基于 C
的 HTTP 客户端

C API 于 libcurl 功能上提供了少于个 API。easy 接口是一个简单的旅
API(意味着当您运要调用 libcurl
时,将会满足你的要,直到好或来误)。多接口可以更加控制
libcurl,您的应用程序可以尽多只协同传输,并决定 libcurl
何时何地移动多少。

拖欠示例使用 easy 接口。该 API
还能够控制数据移动过程(使用回调),但巧而该称所示,使用起来非常简单。清单
3 提供了 HTTP 的 C 语言示例。

清单 3. 使用 libcurl easy 接口的 C HTTP 客户端

               
 #include <stdio.h> 
 #include <string.h> 
 #include <curl/curl.h> 

 #define MAX_BUF     65536 

 char wr_buf[MAX_BUF+1]; 
 int  wr_index; 

 /* 
 * Write data callback function (called within the context of 
 * curl_easy_perform. 
 */ 
 size_t write_data( void *buffer, size_t size, size_t nmemb, void *userp ) 
 { 
  int segsize = size * nmemb; 

  /* Check to see if this data exceeds the size of our buffer. If so, 
   * set the user-defined context value and return 0 to indicate a 
   * problem to curl. 
   */ 
  if ( wr_index + segsize > MAX_BUF ) { 
    *(int *)userp = 1; 
    return 0; 
  } 

  /* Copy the data from the curl buffer into our buffer */ 
  memcpy( (void *)&wr_buf[wr_index], buffer, (size_t)segsize ); 

  /* Update the write index */ 
  wr_index += segsize; 

  /* Null terminate the buffer */ 
  wr_buf[wr_index] = 0; 

  /* Return the number of bytes received, indicating to curl that all is okay */ 
  return segsize; 
 } 


 /* 
 * Simple curl application to read the index.html file from a Web site. 
 */ 
 int main( void ) 
 { 
  CURL *curl; 
  CURLcode ret; 
  int  wr_error; 

  wr_error = 0; 
  wr_index = 0; 

  /* First step, init curl */ 
  curl = curl_easy_init(); 
  if (!curl) { 
    printf("couldn't init curl\n"); 
    return 0; 
  } 

  /* Tell curl the URL of the file we're going to retrieve */ 
  curl_easy_setopt( curl, CURLOPT_URL, "www.exampledomain.com" ); 

  /* Tell curl that we'll receive data to the function write_data, and 
   * also provide it with a context pointer for our error return. 
   */ 
  curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)&wr_error ); 
  curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_data ); 

  /* Allow curl to perform the action */ 
  ret = curl_easy_perform( curl ); 

  printf( "ret = %d (write_error = %d)\n", ret, wr_error ); 

  /* Emit the page if curl indicates that no errors occurred */ 
  if ( ret == 0 ) printf( "%s\n", wr_buf ); 

  curl_easy_cleanup( curl ); 

  return 0; 
 } 

顶上端是必需的 include文本,包括 cURL
根文件。接下来,我定义了点滴单用于传输的变量。第一只变量是 wr_buf,表示以当其中写入传入数据的缓冲区。wr_index意味着缓冲区的当前描绘入索引。

转到 main函数,该函数使用
easy API 进行设置。所有 cURL
调用都由此维护特定请求状态的句子柄进行操作。这叫 CURL指南针引用。本例还创造一个特有之返回码,称为 CURLcode。在用另外 libcurl
函数之前,您需调用 curl_easy_init获取 CURL句柄。接下来,注意 curl_easy_setopt调用的数目。它们为一定的操作配置句柄。对于这些调用,您提供句柄、命令和选择。首先,本例使用CURLOPT_URL指定要获得之
URL。然后,它使用 CURL_WRITEDATA供一个上下文变量(在本例中,它是里的
write 错误变量)。最后,它用 CURLOPT_WRITEFUNCTION指定数量可用时应该调用的函数。在起步
API 之后,API 将下它们读取的数量多次调整用该函数。

只要从头传输,调用 curl_easy_perform。它的干活是基于之前的部署执行传输。调用该函数时,在形成传输或生错误之前该函数不会见返回。main的末梢一步是付返回状态,提交页面读取,最后使 curl_easy_cleanup打消(当用句柄执行完操作后)。

今日探访 write_data函数。该函数是指向一定操作收到多少时调用的回调。注意,当你打网站读取数据时,将写副该多少(write_data)。将朝着回调提供一个缓冲区(包含可用数据)、成员数量及分寸(缓冲中可用数据总量)、上下文指针。第一个任务是承保缓冲区(wr_buf)的空中可以写副数据。如果不够,它以设置上下文指针并回
0,表示出现问题。否则,它将 cURL
缓冲区的数据复制到你的缓冲区,并增加索引,指向要写副的下一个职。本例还息字符串,稍后可以对该行使 printf。最后,它回到 libcurl
操作的字节数量。这将晓 libcurl
数据被取,它为得以摒弃该数额。这就是是打网站以文件读取到内存的对立简便易行的章程。

回页首

基于
Python 的 HTTP 客户端

本节提供的言传身教类似于冲 C 的 HTTP 客户端,不过它使用的凡 Python。Python
是同一种植十分实用之面向对象的脚本语言,在原型化和构建生产软件上面颇突出。示例假要您于熟悉
Python,但下非多,因此不要指望过大。

本条简单的 Python HTTP 客户端使用 pycurl,如清单 4 所示。

清单 4. 使用 libcurl 的 pycurl接口的 Python HTTP
客户端

             
 import sys 
 import pycurl 

 wr_buf = ''

 def write_data( buf ): 
     global wr_buf 
     wr_buf += buf 

 def main(): 
     c = pycurl.Curl() 
     c.setopt( pycurl.URL, 'http://www.exampledomain.com' ) 
     c.setopt( pycurl.WRITEFUNCTION, write_data ) 

     c.perform() 

     c.close() 

 main() 
 sys.stdout.write(wr_buf) 

以 Python 进行原型化

原型化是 Python 的优势之一。它仅仅待充分少的代码就好实现大气功力。使用 C
也许会获取重新好的性能,但是要是你的目的是快捷编码为证实某个概念,那么高级脚本语言是无可取代的,比如
Python。

随即较 C
语言版简单的大多。它首先导入必需的模块(用于规范体系的sys和 pycurl模块)。接下来,它定义
write 缓冲区(wr_buf)。像 C 程序中平等,我声明一个 write_data函数。注意,该函数只是生一个参数:从
HTTP 服务器被读取的数目缓冲区。我将拖欠缓冲区连接到全局 write
缓冲区。main函数首先创建一个 Curl句柄,然后以 setopt方法呢传输定义 URL和 WRITEFUNCTION。它调用 perform办法启动传输并关闭句柄。最后,它调用 main函数,并将 write
缓冲区提交到 stdout。注意,在这种情景下,您不需错误上下文指针,因为你使用了
Python 字符串连接,这便是说你不会见以大小固定的字符串。

回页首

结束语

本文仅略介绍了
libcurl,介绍了它们支持之强协议及语言。希望就能显得她如何轻松构建以应用层协议(如
HTTP)的应用程序。libcurl 网站(见 参考资料)提供了许多演示和行之有效之文档。下一样软支付
Web 浏览器、爬行器或外有应用层协议要求的应用程序时,试试
libcurl。它肯定能够大大减少您的开销时间,并摸索回编码的意。

参考资料

学习

  • cURL大凡一个命令行工具及库房,实现了各种客户端协议。它支持
    12 种以上之协议,包括 FTP、HTTP、Telnet
    以及其它安全变体。许多平台达成还能找到 cURL,包括 Linux、AIX、BSD 和
    Solaris,它支持 30 多种语言。

  • PycURL凡是 libcurl API
    之上的一个薄层,PycURL 速度挺抢。使用 PycURL,您可利用 libcurl
    库开发 Python 应用程序。

  • 说到应用程序灵活性,您得在 “之所以 Guile
    编写脚本”
    中了解再多关于以下论功能集成及应用程序的始末。

  • 若听听有关软件开发人员之趣采访和议论,请查看 developerWorks
    网络广播。

  • 叩问最新的 developerWorks 技能活动 和 网广播。

  • 在 Twitter 上跟随 developerWorks。

  • 查看最近拿当海内外举办的面向 IBM
    开放源码开发人员的研讨会、交易展览、网络播放和另 活动。

  • 访问 developerWorks 开源专区得丰富的
    how-to 信息、工具和档次更新,帮助您用开放源码技术进行支付,并和 IBM
    产品结合使用。

  • 翻免费的 developerWorks On demand
    演示,观看并问询
    IBM 及开源技术及活功能。

取得产品以及技能

  • 使用 IBM
    试用软件改良而的下一个开发品种,这些软件可透过下载中心得到。

  • 下载 IBM
    产品评估版 或 在 IBM SOA Sandbox
    中研究在线试用本,开始利用来源
    DB2®、Lotus®、Rational®、Tivoli®和
    WebSphere®的应用程序开发工具和中间件产品。

fatal error: curl/curl.h: No such file or directory | Ubuntu 12.04 from alexsleat.co.uk – Google Chr (2013/7/26 16:49:05)

fatal error: curl/curl.h: No such file or directory | Ubuntu 12.04

fatal error: curl/curl.h: No such file or directory

If you’re missing the curl/curl.h header file, chances are you’re just
missing the correct dev package file for the curl library.

sudo apt-get install libcurl4-gnutls-dev

That should fix it.

curl_easy_getinfo() — 从 curl 句柄里获得附加信|Functions – 曲径通幽 – Standing on the shoulders of giants – Goo (2013/5/23 17:52:30)

curl_easy_getinfo()
函数原型声明如下:

?

1
2
#include <curl/curl.h>
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );

用该函数可以于呼吁求
curl 会话中之相关消息。注意,第 3 独参数必须是一个 long
型,或char型,或curl_slist型,抑或是double型的指针。函数所求信息只有当函数返回 CURLE_OK 常才会被有效填充,该函数一般用当
perform 函数(如 curl_easy_perform() )之后。


2 独参数有众多抉择,每个选项都产生其相应的意义:

CURLINFO_SIZE_DOWNLOAD
以该选项时要求第
3 个参数是单 double
型的指针,这样以同不成传输成功后会见拿本次传输所下载的字节数赋值到指针所指向的
double 型变量中。注意,这个字节数只能反映近年来同次的下载。

CURLINFO_SPEED_DOWNLOAD
欠选择要求传递一个
double
型参数指针,用以吸纳下载的平均速度,这个速度不是就是经常进度,而是下载就后底快,单位是 字节/秒 。

CURLINFO_TOTAL_TIME
该选择要求传递一个
double 指针到函数中,double
型变量指示了导的总耗时(单位吗秒),这个总的辰里连了域名解析,以及
TCP 连接过程被所用之时间。

CURLINFO_CONTENT_TYPE
该选择获得
HTTP 中于服务器端收到的头中的 Content-Type 信息。
测试代码

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
 
int main(void)
{
    CURL *curl;
    CURLcode res;
 
    FILE *fp;
    if (!(fp = fopen ("info.html", "w+"))) {
        perror("fopen error:");
        exit (EXIT_FAILURE);
    }    
 
    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://www.baidu.com/");
        res = curl_easy_perform(curl);
 
        if(CURLE_OK == res) {
            char *contype;
            res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contype);
 
            if((CURLE_OK == res) && ct)
                fwrite (contype, 1, strlen(contype), fp);
                fwrite ("\n\0", 1, 1, fp);  //为了在 vi 里看起来完全正常,需要添加换行符和 NULL
        }
 
        close (fp);
        curl_easy_cleanup(curl);
    }
    return 0;
}

运转输出:

$ cat info.html 
text/html;charset=gb2312

CURLINFO_FILETIME
用该选项时需要传递一个
long 型指针到函数,该 long
型变量中保存了远程主机及之文书之近期改日期。如果采取该值时函数返回
-1,原因是多元的(比如有不为人知的,比如服务器对之日期信息做了隐形,或者是服务器不支持获取文档时之通令等等)。需要注意的凡,在运该选项时,需要事先以
curl_easy_setopt() 函数着运用 CURLOPT_FILETIME 选项,然后重新运行
curl_easy_perform() 后,方会获服务器上的文档时。

CURLINFO_CONTENT_LENGTH_DOWNLOAD
下该选项时要求传递一个
double 型指针到函数中,该 double
型变量用来存放所而下载文件(或者是所假设查询的文件)的 content-length
(文档长度) 的信息。如果文件大小无法获取,那么函数返回值为 -1 。

CURLINFO_FILETIME
和 CURLINFO_CONTENT_LENGTH_DOWNLOAD 选项下示例,下面代码获取 FTP
服务器上之一个文书的光阴和大小信息:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <curl/easy.h>
 
static size_t save_header(void *ptr, size_t size, size_t nmemb, void *data)
{
        return (size_t)(size * nmemb);
}
 
int main(void)
{
        char ftpurl[] = "ftp://vh492363:2tg96d33@121.15.245.7/www/bbs/favicon.ico";
        CURL *curl;
        CURLcode res;
 
        const time_t filetime;
        const double filesize;
        const char *filename = strrchr(ftpurl, '/') + 1;
 
        curl_global_init(CURL_GLOBAL_ALL);
 
        curl = curl_easy_init();
        if (curl) {
                curl_easy_setopt(curl, CURLOPT_URL, ftpurl);
                curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
                curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
                curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, save_header);
                curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
                //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
 
                curl_easy_perform(curl);
 
                if (res != CURLE_OK) {
                        res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
                        if ((CURLE_OK == res) && filetime)
                                printf ("filetime %s: %s", filename, ctime(&filetime));
                        res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
 
                       if ((CURLE_OK == res) && (filesize > 0))
                                printf ("filesize %s: %0.0f bytes\n", filename, filesize);
                } else {
                        fprintf (stderr, "curl told us %d\n", res);
                }
        curl_easy_cleanup(curl);
        }
 
        curl_global_cleanup();
 
        return 0;
}

运转输出:

beyes@debian:~/C/curl$ ./getftpinfo class=”Apple-converted-space”> 
Last-Modified: Mon, 25 Apr 2011 15:26:56 GMT
Content-Length: 1758
Accept-ranges: bytes
filetime favicon.ico: Mon Apr 25 11:26:56 2011
filesize favicon.ico: 1758 bytes

[ 此帖被beyes在2011-07-04 09:47还编辑 ]

C++ 用libcurl库进行http通讯网络编程 – 绿色冰点 – 博客园 – Google Chrome (2013/5/23 16:59:53)

http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html

 

 

目录索引:

图片 3

一、LibCurl基本编程框架
二、一些基本的函数
三、curl_easy_setopt函数部分选项介绍
四、curl_easy_perform 函数说明(error 状态码)
五、libcurl使用的HTTP消息头
六、获取http应答头信息
七、多线程问题
八、什么时候libcurl无法正常工作
九、关于密码
十、HTTP验证
十一、代码示例
     1.基本的http GET/POST操作
     2 获取html网页
     3 网页下载保存实例
     4 进度条实例显示文件下载进度
     5 断点续传实例

图片 4

 

一致、LibCurl基本编程框架
libcurl凡是一个跨平台的网络协议库,支持http,
https, ftp, gopher, telnet, dict, file, 和ldap
协议。libcurl同样支撑HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传,
HTTP基本表单上污染,代理,cookies,和用户征。想使明了还多关于libcurl的牵线,可以交国有网 http://curl.haxx.se/上询问,在此间不再详述。

win32本的libcurl下充斥地址:http://curl.freeby.pctools.cl/download/libcurl-7.18.0-win32-msvc.zip

以基于LibCurl的次里,主要以callback function
(回调函数)的样式好传输任务,用户在起步传输前设置好各项参数与回调函数,当满足条件时libcurl将调用用户的回调函数实现特定功能。下面是采用libcurl完成传输任务的流水线:

1.       调用curl_global_init()初始化libcurl
2.       调用curl_easy_init()函数得到
easy interface型指针
3.       调用curl_easy_setopt()安导选项
4.       根据curl_easy_setopt()装的传输选项,实现回调函数以完成用户特定任务
5.       调用curl_easy_perform()函数完成传输任务
6.       调用curl_easy_cleanup()放出内存
于整过过程被安curl_easy_setopt()参数是最最关键的,几乎所有的libcurl程序都设用其。

第二、一些主导的函数
1.CURLcode
curl_global_init(long flags);

描述:
此函数只能用同样次于。(其实在调用curl_global_cleanup 函数后依旧只是更就此)
假如是函数在curl_easy_init函数调用时还并未调用,它说由libcurl库自动调用,于是基本上线程下最为好积极调用该函数以防止在线程中curl_easy_init时频繁调用。

小心:虽然libcurl是线程安全之,但curl_global_init是免可知确保线程安全之,所以不用当每个线程中还调用curl_global_init,应该将拖欠函数的调用放在主线程中。
参数:flags
CURL_GLOBAL_ALL 
                    //初始化所有的恐怕的调用。
CURL_GLOBAL_SSL 
                    //初始化支持 安全法接字层。
CURL_GLOBAL_WIN32 
          //初始化win32仿接字库。
CURL_GLOBAL_NOTHING         //没有额外的初始化。

2 void
curl_global_cleanup(void);

叙述:在结束libcurl使用的下,用来针对curl_global_init做的干活清理。类似于close的函数。

留神:虽然libcurl是线程安全的,但curl_global_cleanup是勿克保证线程安全的,所以并非以每个线程中都调用curl_global_init,应该拿该函数的调用放在主线程中。

3 char
*curl_version( );

叙: 打印当前libcurl库的本子。

4 CURL
*curl_easy_init( );

描述:
curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样).
相应的在调用了时如果用curl_easy_cleanup函数清理.
一般curl_easy_init意味着一个对话的开始.
它会返回一个easy_handle(CURL*目标), 一般都为此当easy系列的函数中.

5 void
curl_easy_cleanup(CURL *handle);

描述:
斯调用用来了一个碰头话.与curl_easy_init配合着用. 
参数:
CURL类型的指针.

6 CURLcode
curl_easy_setopt(CURL *handle, CURLoption option,
parameter);

讲述: 这个函数最重大了.几乎所有的curl
程序还如再三的施用它.它报告curl库.程序将起什么样的行为.
比如要查一个网页的html代码等.(这个函数有些像ioctl函数)参数:
1 CURL类型的指针
2 各种CURLoption类型的选择项.(都当curl.h库里生定义,man 也得以查阅相)
3 parameter 这个参数
既好是独函数的指针,也可是有对象的指针,也可以是只long型的变量.它用啊就在第二独参数.
CURLoption 这个参数的取值很多.具体的可以查阅man手册.

7 CURLcode
curl_easy_perform(CURL *handle);

叙:这个函数在初始化CURL类型的指针 以及curl_easy_setopt完成后调整用.
就像字面的意思所说perform就比如是只舞台.让咱安的
option 运作起来.参数:
CURL类型的指针.

三、 curl_easy_setopt函数部分选项介绍
本节首要介绍curl_easy_setopt中同http相关的参数。该函数是curl中颇主要之函数,curl所有安装都是以该函数着就的,该函数的装置选项多,注意本节的阐述的才是一对大选项。

1.     CURLOPT_URL 
装访问URL

2.       CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
转头调函数原型为:size_t function( void
*ptr, size_t size, size_t nmemb, void
*stream); 
函数将于libcurl接收至数码后被调用,因此函数多举行多少保存之职能,如处理下载文件。CURLOPT_WRITEDATA
用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的源。

而您没有经过CURLOPT_WRITEFUNCTION属性给easy
handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简短的将接收及之数码打印至正规输出。你吗可以经
CURLOPT_WRITEDATA属性给默认回调函数传递一个早已打开的公文指针,用于将数据输出到文件里。

3.      CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
转头调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb,
void *stream); libcurl一旦接受至http
头部数后以调用该函数。CURLOPT_WRITEDATA
传递指针给libcurl,该指针表明CURLOPT_HEADERFUNCTION
函数的stream指针的根源。

4.       CURLOPT_READFUNCTION
CURLOPT_READDATA
libCurl需要读取数据传递让长途主机时用调用CURLOPT_READFUNCTION指定的函数,函数原型是:size_t
function(void *ptr, size_t size, size_t nmemb,void *stream).
CURLOPT_READDATA 表明CURLOPT_READFUNCTION函数原型中的stream指针来源。

5.       CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
以及数据传速度相关的参数。CURLOPT_PROGRESSFUNCTION
指定的函数正常情况下各个秒为libcurl调用同一破,为了使CURLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须吃设置为false,CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的率先只参数

6.       CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于设置导时间,CURLOPT_CONNECTIONTIMEOUT
设置连接等时

  1.       CURLOPT_FOLLOWLOCATION
    安装重定位URL

8.       CURLOPT_RANGE:
CURLOPT_RESUME_FROM:
断点续传相关设置。CURLOPT_RANGE 指定char
*参数传递给libcurl,用于指明http域的RANGE头域,例如:
表示头500个字节:bytes=0-499
意味着第二只500字节:bytes=500-999
代表最终500独字节:bytes=-500
意味着500字节以后的范围:bytes=500-
首先只及尾声一个字节:bytes=0-0,-1
又指定几个限:bytes=500-600,601-999
CURLOPT_RESUME_FROM
传递一个long参数为libcurl,指定你盼开传递的 偏移量。

四、 curl_easy_perform 函数说明(error
状态码)

该函数是水到渠成curl_easy_setopt指定的兼具选项,本节重点介绍curl_easy_perform的回值。返回0意味一切ok,非0代表错误产生。主要错误码说明:
1.    CURLE_OK 
    任务成功所有都吓
2     CURLE_UNSUPPORTED_PROTOCOL
    不支持之商谈,由URL的头指定
3     CURLE_COULDNT_CONNECT
    不克连至remote 主机或者代理
4     CURLE_REMOTE_ACCESS_DENIED
    访问于拒绝
5     CURLE_HTTP_RETURNED_ERROR
    Http返回错误
6     CURLE_READ_ERROR
读本地文件漏洞百出

假若获得详细的缪描述字符串,可以由此const char
*curl_easy_strerror(CURLcode errornum )
 这个函数取得.

 

五、libcurl使用的HTTP消息头
   
当以libcurl发送http请求时,它见面活动抬高一些http头。我们好透过CURLOPT_HTTPHEADER属性手动替换、添加或去相应
的HTTP消息头。
    Host
    http1.1(大部分http1.0)版本都求客户端请求提供这信息头。
    Pragma
    “no-cache”。表示不要缓冲数据。
    Accept
    “*/*”。表示同意收取任何项目的数。
    Expect
   
以POST的道向HTTP服务器交由请求时,libcurl会设置该消息头为”100-continue”,它要求服务器在正式处理该要之前,返回一
个”OK”消息。如果POST的数量十分粗,libcurl可能未会见装该消息头。
从定义选项
   
当前越来越多的商议还构建以HTTP协议之上(如:soap),这根本归功给HTTP的可靠性,以及让大应用的代理支持(可以穿透大部分防火墙)。
这些协议的采取方法跟传统HTTP可能出好非常的不同。对这,libcurl作了酷好的支持。
    自定义请求方式(CustomRequest)
    HTTP支持GET,
HEAD或者POST提交请求。可以安装CURLOPT_CUSTOMREQUEST来安由定义之呼吁方式,libcurl默认以GET方式交给请求:
    curl_easy_setopt(easy_handle,
CURLOPT_CUSTOMREQUEST, “MYOWNREQUEST”); 

修改消息头
   
HTTP协议提供了消息头,请求消息头用于告诉服务器如何处理要;响应消息头则告知浏览器如何处理接收及之数目。在libcurl中,你可以随心所欲之添加
这些消息头:

图片 5

struct curl_slist *headers=NULL; /* init to NULL is important */
headers = curl_slist_append(headers, "Hey-server-hey: how are you?");
headers = curl_slist_append(headers, "X-silly-content: yes");
/* pass our list of custom made headers */
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(easyhandle); /* transfer http */
curl_slist_free_all(headers); /* free the header list */

图片 6

对于已经存在的消息头,可以再安装它的价值:

headers = curl_slist_append(headers, "Accept: Agent-007"); 
headers = curl_slist_append(headers, "Host: munged.host.line"); 

抹消息头
对此一个既是的消息头,设置它的内容呢空,libcurl在发送请求时即无见面以提交该消息头:

headers = curl_slist_append(headers, "Accept:");

** 

六、获取http应答头信息

   
发出http请求后,服务器会回来应答头信息以及回答数据,如果单独是打印应答头的有内容,则直接可以由此curl_easy_setopt(curl,
CURLOPT_HEADERFUNCTION,
打印函数)的措施来就,这里需要取得的凡许答头中一定的音讯,比如应答码、cookies列表等,则要经下面这个函数:
    CURLcode
curl_easy_getinfo(CURL *curl, CURLINFO info, … ); 

    info参数就是咱要得到之情节,下面是有些参数值:
    1.CURLINFO_RESPONSE_CODE
    获取应答码
    2.CURLINFO_HEADER_SIZE
    头大小
    3.CURLINFO_COOKIELIST
    cookies列表

   
除了获取应答信息外,这个函数还能够得curl的一些里边消息,如要时、连接时间等等。

    更多的参数可以参考API文档。

 

七、多线程问题
    首先一个核心原则就是是:绝对不应在线程之间联合享同一个libcurl
handle(CURL *对象),不管是easy handle还是multi
handle(本文特介绍easy_handle)。一个线程每次只能使用一个handle。
    libcurl是线程安全的,但发生少数点不同:信号(signals)和SSL/TLS handler。
信号用于超时失效名字解析(timing out name
resolves)。libcurl依赖其他的堆栈来支撑SSL/STL,所以用多线程的计访HTTPS或FTPS的URL时,应该满足这些库对多线程
操作的一部分要求。详细可参照:
    OpenSSL: http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION

    GnuTLS: http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html

    NSS: 宣称是多线程安全之。

八、什么时libcurl无法正常办事
   
传输失败总是发生原因之。你恐怕错误的装了部分libcurl的特性或者无科学的知一些性能之含义,或者是长途主机返回一些无法让科学解析的情节。
    这里产生一个黄金法则来处理这些问题:将CURLOPT_VERBOSE属性设置为1,libcurl会输出通信过程遭到之有的细节。如果采取的凡http协
议,请求头/响应头也会于输出。将CURLOPT_HEADER设为1,这些头信息用应运而生在信息的内容中。
    当然不可否认的凡,libcurl还在bug。
    如果你针对系的商事了解进一步多,在动用libcurl时,就逾不易于犯错。

九、关于密码
   
客户端向服务器发送请求时,许多商谈还求提供用户称以及密码。libcurl提供了多法来安装它们。
    一些合计支持以URL中直接指定用户称与密码,类似于:
protocol://user:password@example.com/path/。libcurl能是的鉴别这种URL中之用户称以及密码并尽
相应的操作。如果您提供的用户称与密码被出特殊字符,首先应本着该展开URL编码。
    也堪透过CURLOPT_USERPWD属性来设置用户称及密码。参数是格式如
“user:password ”的字符串:
    curl_easy_setopt(easy_handle,
CURLOPT_USERPWD, “user_name:password”)

   
有时候在看代理服务器的当儿,可能随时要求提供用户称以及密码进行用户身份验证。这种情况下,libcurl提供了其它
一个属性CURLOPT_PROXYUSERPWD:
    curl_easy_setopt(easy_handle,
CURLOPT_PROXYUSERPWD, “user_name:password”);
 
   
在UNIX平台下,访问FTP的用户称和密码或会见于保留于$HOME/.netrc文件中。libcurl支持直接从之文件被获得用户称以及密码:
    curl_easy_setopt(easy_handle,
CURLOPT_NETRC, 1L); 

   
在采用SSL时,可能要提供一个私钥用于数据安全传输,通过CURLOPT_KEYPASSWD来装私钥:
    curl_easy_setopt(easy_handle,
CURLOPT_KEYPASSWD, “keypassword”);

十、HTTP验证
    在用HTTP协议时,客户端有酷多种法向服务器提供证明信息。默认的
HTTP验证方法是”Basic”,它以用户称及密码为明的计、经Base64编码后保存在HTTP请求头中,发朝服务器。当然这不绝安全。
    当前版本的libcurl支持之求证措施有:basic, Digest, NTLM, Negotiate,
GSS-Negotiate and
SPNEGO。(译者感叹:搞Web这么长年累月,尽然不知道这些Http的证明措施,实在惭愧。)可以由此CURLOPT_HTTPAUTH属性来设置具体
的印证办法:
    curl_easy_setopt(easy_handle,
CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

   
向代理服务器发送验证信息时,可以透过CURLOPT_PROXYAUTH设置验证办法:
    curl_easy_setopt(easy_handle,
CURLOPT_PROXYAUTH, CURLAUTH_NTLM);

    也堪又设置多证方式(通过按位与),
使用‘CURLAUTH_ANY‘将同意libcurl可以选其它它所支持的验证方式。通过CURLOPT_HTTPAUTH或
CURLOPT_PROXYAUTH属性设置的又验证措施,libcurl会在运作时选一样栽它认为是太好的点子同服务器通信:
    curl_easy_setopt(easy_handle,
CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC); 

    //
curl_easy_setopt(easy_handle, CURLOPT_HTTPAUTH,
CURLAUTH_ANY);

 

十一、代码示例

下载的libcurl中打带了众多演示代码,在docs\examples目录下,建议下充斥该库后好看一下这些代码。

libcurl的API文档在docs\libcurl\index.html中。

1.基本的http GET/POST操作

图片 7

#include <stdio.h>
#include <curl/curl.h>
bool getUrl(char *filename)
{
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "w")) == NULL)  // 返回结果用文件存储
        return false;
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Accept: Agent-007");
    curl = curl_easy_init();    // 初始化
    if (curl)
    {
        //curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");// 代理
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改协议头
        curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //将返回的http头输出到fp指向的文件
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp); //将返回的html主体数据输出到fp指向的文件
        res = curl_easy_perform(curl);   // 执行
        if (res != 0) {

            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
        }
        fclose(fp);
        return true;
    }
}
bool postUrl(char *filename)
{
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "w")) == NULL)
        return false;
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86");    // 指定post内容
        //curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");
        curl_easy_setopt(curl, CURLOPT_URL, " http://mail.sina.com.cn/cgi-bin/login.cgi ");   // 指定url
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    fclose(fp);
    return true;
}
int main(void)
{
    getUrl("/tmp/get.html");
    postUrl("/tmp/post.html");
}

图片 8

编译gcc  get_post.c 
-o get_post –lcurl

./ get_post

2 获取html网页

图片 9

#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    CURL *curl;             //定义CURL类型的指针
CURLcode res;           //定义CURLcode类型的变量,保存返回状态码
    if(argc!=2)
    {
        printf("Usage : file <url>;\n");
        exit(1);
    }

    curl = curl_easy_init();        //初始化一个CURL类型的指针
    if(curl!=NULL)
    {
        //设置curl选项. 其中CURLOPT_URL是让用户指 定url. argv[1]中存放的命令行传进来的网址
        curl_easy_setopt(curl, CURLOPT_URL, argv[1]);        
        //调用curl_easy_perform 执行我们的设置.并进行相关的操作. 在这 里只在屏幕上显示出来.
        res = curl_easy_perform(curl);
        //清除curl操作.
        curl_easy_cleanup(curl);
    }
    return 0;
}

图片 10

编译gcc 
get_http.c  -o get_http –lcurl

./
get_http www.baidu.com

 

3 网页下载保存实例

图片 11

// 采用CURLOPT_WRITEFUNCTION 实现网页下载保存功能
#include <stdio.h>;
#include <stdlib.h>;
#include <unistd.h>;

#include <curl/curl.h>;
#include <curl/types.h>;
#include <curl/easy.h>;

FILE *fp;  //定义FILE类型指针
//这个函数是为了符合CURLOPT_WRITEFUNCTION而构造的
//完成数据保存功能
size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)  
{
    int written = fwrite(ptr, size, nmemb, (FILE *)fp);
    return written;
}

int main(int argc, char *argv[])
{
    CURL *curl;

    curl_global_init(CURL_GLOBAL_ALL);  
    curl=curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, argv[1]);  

    if((fp=fopen(argv[2],"w"))==NULL)
    {
        curl_easy_cleanup(curl);
        exit(1);
    }
////CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);  
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    exit(0);
}

图片 12

编译gcc  save_http.c  -o
save_http –lcurl
./ save_http www.baidu.com
  /tmp/baidu

4 快久实例显示文件下载速度

图片 13

// 采用CURLOPT_NOPROGRESS, CURLOPT_PROGRESSFUNCTION    CURLOPT_PROGRESSDATA 实现文件传输进度提示功能
//函数采用了gtk库,故编译时需指定gtk库
//函数启动专门的线程用于显示gtk 进度条bar
#include <stdio.h>
#include <gtk/gtk.h>
#include <curl/curl.h>
#include <curl/types.h> /* new for v7 */
#include <curl/easy.h> /* new for v7 */

GtkWidget *Bar;
////这个函数是为了符合CURLOPT_WRITEFUNCTION而构造的
//完成数据保存功能
size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
  return fwrite(ptr, size, nmemb, stream);
}
//这个函数是为了符合CURLOPT_READFUNCTION而构造的
//数据上传时使用
size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
  return fread(ptr, size, nmemb, stream);
}
//这个函数是为了符合CURLOPT_PROGRESSFUNCTION而构造的
//显示文件传输进度,t代表文件大小,d代表传 输已经完成部分
int my_progress_func(GtkWidget *bar,
                     double t, /* dltotal */
                     double d, /* dlnow */
                     double ultotal,
                     double ulnow)
{
/*  printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
  gdk_threads_enter();
  gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);
  gdk_threads_leave();
  return 0;
}

void *my_thread(void *ptr)
{
  CURL *curl;
  CURLcode res;
  FILE *outfile;
  gchar *url = ptr;

  curl = curl_easy_init();
  if(curl)
  {
    outfile = fopen("test.curl", "w");

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);

    res = curl_easy_perform(curl);

    fclose(outfile);
    /* always cleanup */
    curl_easy_cleanup(curl);
  }

  return NULL;
}

int main(int argc, char **argv)
{
  GtkWidget *Window, *Frame, *Frame2;
  GtkAdjustment *adj;

  /* Must initialize libcurl before any threads are started */
  curl_global_init(CURL_GLOBAL_ALL);

  /* Init thread */
  g_thread_init(NULL);

  gtk_init(&argc, &argv);
  Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  Frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(Window), Frame);
  Frame2 = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN);
  gtk_container_add(GTK_CONTAINER(Frame), Frame2);
  gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5);
  adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
  Bar = gtk_progress_bar_new_with_adjustment(adj);
  gtk_container_add(GTK_CONTAINER(Frame2), Bar);
  gtk_widget_show_all(Window);

  if (!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
    g_warning("can't create the thread");


  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();
  return 0;
}

图片 14

编译export
PKG_CONFIG_PATH=/usr/lib/pkgconfig/
gcc progress.c –o
progress ` pkg-config –libs –cflags gtk+-2..0` -lcurl
–lgthread-2.0
./ progress  http://software.sky-union.cn/index.asp

5 断点续传实例

图片 15

//采用CURLOPT_RESUME_FROM_LARGE 实现文件断点续传功能
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>

#include <curl/curl.h>
//这个函数为CURLOPT_HEADERFUNCTION参数构造
/* 从http头部获取文件size*/
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
       int r;
       long len = 0;

       /* _snscanf() is Win32 specific */
       // r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
 r = sscanf(ptr, "Content-Length: %ld\n", &len);
       if (r) /* Microsoft: we don't read the specs */
              *((long *) stream) = len;

       return size * nmemb;
}

/* 保存下载文件 */
size_t wirtefunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
        return fwrite(ptr, size, nmemb, stream);
}

/*读取上传文件 */
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
       FILE *f = stream;
       size_t n;

       if (ferror(f))
              return CURL_READFUNC_ABORT;

       n = fread(ptr, size, nmemb, f) * size;

       return n;
}

// 下载 或者上传文件函数
int download(CURL *curlhandle, const char * remotepath, const char * localpath,
           long timeout, long tries)
{
       FILE *f;
       curl_off_t local_file_len = -1 ;
       long filesize =0 ;

       CURLcode r = CURLE_GOT_NOTHING;
       int c;
  struct stat file_info;
  int use_resume = 0;
  /* 得到本地文件大小 */
  //if(access(localpath,F_OK) ==0)

    if(stat(localpath, &file_info) == 0) 
     {
        local_file_len =  file_info.st_size;
        use_resume  = 1;
      }
  //采用追加方式打开文件,便于实现文件断点续传工作
       f = fopen(localpath, "ab+"); 
       if (f == NULL) {
              perror(NULL);
              return 0;
       }

       //curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);

       curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);

              curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, timeout);  // 设置连接超时,单位秒
       //设置http 头部处理函数
       curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
       curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &filesize);
 // 设置文件续传的位置给libcurl
       curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM_LARGE, use_resume?local_file_len:0);

       curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, f);
       curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, wirtefunc);

       //curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
       //curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
       curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 1L);
       curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);


  r = curl_easy_perform(curlhandle);


       fclose(f);

       if (r == CURLE_OK)
              return 1;
       else {
              fprintf(stderr, "%s\n", curl_easy_strerror(r));
              return 0;
       }
}

int main(int c, char **argv) {
       CURL *curlhandle = NULL;

       curl_global_init(CURL_GLOBAL_ALL);
       curlhandle = curl_easy_init();

       //download(curlhandle, "ftp://user:pass@host/path/file", "C:\\file", 0, 3);
  download(curlhandle , "http://software.sky-union.cn/index.asp","/work/index.asp",1,3);
       curl_easy_cleanup(curlhandle);
       curl_global_cleanup();

       return 0;
}

图片 16

编译gcc  resume.c  -o
resume –lcurl
./ resume  

Linux libcurl使用(一)(收藏)_留风的贝壳_百度空间 – Google Chrome (2013/5/23 15:17:01)

Linux libcurl使用(一)(收藏)

LibCurl编程 http://wangjiajun53880.blog.163.com/blog/static/117001394200992011257363/

Linux   2009-10-20 13:07    阅读   
评论字号: 大 中 小

2.1 LibCurl编程流程

每当基于LibCurl的主次里,主要运用callback function
(回调函数)的样式好传输任务,用户在开行传输前设置好个参数和回调函数,当满足条件时libcurl将调用用户之回调函数实现特定功能。下面是运libcurl完成传输任务之流程:

1.       调用curl_global_init()初始化libcurl

2.       调用 curl_easy_init()函数得到 easy interface型指针

3.       调用curl_easy_setopt设置导选项

4.      
根据curl_easy_setopt设置的传导选项,实现回调函数以好用户特定任务

5.       调用curl_easy_perform()函数完成传输任务

6.       调用curl_easy_cleanup()释放内存

以整过过程被安装curl_easy_setopt()参数是极端紧要的,几乎有的libcurl程序都使运用它们。

2.2 重要函数

1.CURLcode curl_global_init(long flags);

描述:
夫函数只能用同一坏。(其实在调用curl_global_cleanup 函数后还是可另行用)
一旦这个函数在curl_easy_init函数调用时还尚无调用,它摆由libcurl库自动就。
参数:flags
CURL_GLOBAL_ALL                      //初始化所有的恐怕的调用。
CURL_GLOBAL_SSL                      //初始化支持 安全法接字层。
CURL_GLOBAL_WIN32            //初始化win32法接字库。
CURL_GLOBAL_NOTHING         //没有额外的初始化。

2 void curl_global_cleanup(void);
讲述:在竣工libcurl使用的下,用来对curl_global_init做的劳作清理。类似于close的函数。
3 char *curl_version( );
叙: 打印当前libcurl库的版本。
4 CURL *curl_easy_init( );
描述:
curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样).
相应的在调用了时只要用curl_easy_cleanup函数清理.
一般curl_easy_init意味着一个会话的开始.
它的返回值一般都用当easy系列的函数中.
5 void curl_easy_cleanup(CURL *handle);
描述:
夫调用用来终止一个晤话.与curl_easy_init配合着用. 
参数:
CURL类型的指针.
6 CURLcode curl_easy_setopt(CURL *handle, CURLoption option,
parameter);
讲述: 这个函数最要了.几乎所有的curl
程序还设反复之采用它.它报告curl库.程序将发安的行为.
比如要翻看一个网页的html代码等.(这个函数有些像ioctl函数)参数:
1 CURL类型的指针
2 各种CURLoption类型的选择项.(都于curl.h库里来定义,man 也堪查相)
3 parameter 这个参数
既好是只函数的指针,也足以是某某对象的指针,也得是个long型的变量.它用什么就取决第二只参数.
CURLoption 这个参数的取值很多.具体的可翻man手册.
7 CURLcode curl_easy_perform(CURL
*handle);描述:这个函数在初始化CURL类型的指针
以及curl_easy_setopt完成后调整用.
就像字面的意思所说perform就如是只舞台.让咱安的
option 运作起来.参数:
CURL类型的指针.

3.3 curl_easy_setopt函数介绍

本节要介绍curl_easy_setopt中与http相关的参数。注意本节的阐释都是因libcurl作为主导,其它为合理来阐释的。

1.     CURLOPT_URL 
设置访问URL

2.       CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
扭动调函数原型为:size_t function( void *ptr, size_t size, size_t
nmemb, void *stream);
函数将以libcurl接收到数量后叫调用,因此函数多开多少保存之功效,如处理下载文件。CURLOPT_WRITEDATA
用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来。

3.      CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
掉调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb,
void *stream); libcurl一旦接收至http
头部数后将调用该函数。CURLOPT_WRITEDATA
传递指针给libcurl,该指针表明CURLOPT_HEADERFUNCTION
函数的stream指针的起源。

4.       CURLOPT_READFUNCTION CURLOPT_READDATA
libCurl需要读取数据传递给长途主机时以调用CURLOPT_READFUNCTION指定的函数,函数原型是:size_t
function(void *ptr, size_t size, size_t nmemb,void *stream).
CURLOPT_READDATA 表明CURLOPT_READFUNCTION函数原型中之stream指针来源。

5.      
CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
跟数据传速度相关的参数。CURLOPT_PROGRESSFUNCTION
指定的函数正常状况下各秒为libcurl调用平等不良,为了要CURLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须叫装置也false,CURLOPT_PROGRESSDATA指定的参数将用作CURLOPT_PROGRESSFUNCTION指定函数的首先单参数

6.       CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于设置导时间,CURLOPT_CONNECTIONTIMEOUT
设置连接等时

7.       CURLOPT_FOLLOWLOCATION
安重定位URL

CURLOPT_RANGE: CURLOPT_RESUME_FROM:
断点续传相关设置。CURLOPT_RANGE 指定char
*参数传递给libcurl,用于指明http域的RANGE头域,例如:
表示头500个字节:bytes=0-499
表示第二独500字节:bytes=500-999
代表最终500个字节:bytes=-500
意味着500字节以后的界定:bytes=500-
第一独及终极一个字节:bytes=0-0,-1

再者指定几单限:bytes=500-600,601-999
    CURLOPT_RESUME_FROM
传递一个long参数为libcurl,指定你要开传递的

偏移量。

3.4 curl_easy_perform 函数说明(error 状态码)

该函数完成curl_easy_setopt指定的具备选项,本节重点介绍curl_easy_perform的回来值。返回0意味一切ok,非0代表错误产生。主要错误码说明:
1.    CURLE_OK 
    任务就所有还吓

2     CURLE_UNSUPPORTED_PROTOCOL

    不支持之说道,由URL的脑袋指定

3     CURLE_COULDNT_CONNECT

    不克连至remote 主机或者代理

4     CURLE_REMOTE_ACCESS_DENIED

    访问于驳回

5     CURLE_HTTP_RETURNED_ERROR

    Http返回错误

6           CURLE_READ_ERROR
读本地文件漏洞百出

3.1 获取html网页

view plaincopy to clipboardprint?
#include <stdio.h>;   
#include <stdlib.h>;   
#include <unistd.h>;   

#include <curl/curl.h>;   
#include <curl/types.h>;   
#include <curl/easy.h>;   

FILE *fp; //定义FILE类型指针   

size_t write_data(void *ptr, size_t size, size_t nmemb, void
*stream) //这个函数是为了契合CURLOPT_WRITEFUNCTION, 而构造的   
{   
    int written = fwrite(ptr, size, nmemb, (FILE *)fp);   
    return written;   
}   

int main(int argc, char *argv[])   
{   
    CURL *curl;   

    curl_global_init(CURL_GLOBAL_ALL);     
    curl=curl_easy_init();   
    curl_easy_setopt(curl, CURLOPT_URL, argv[1]);     

    if((fp=fopen(argv[1],”w”))==NULL)   
    {   
        curl_easy_cleanup(curl);   
        exit(1);   
    }   
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
//CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理   
    curl_easy_perform(curl);   
    curl_easy_cleanup(curl);   
    exit(0);   

#include <stdio.h>;
#include <stdlib.h>;
#include <unistd.h>;

#include <curl/curl.h>;
#include <curl/types.h>;
#include <curl/easy.h>;

FILE *fp; //定义FILE类型指针

size_t write_data(void *ptr, size_t size, size_t nmemb, void
*stream) //这个函数是为着契合CURLOPT_WRITEFUNCTION, 而构造的
{
    int written = fwrite(ptr, size, nmemb, (FILE *)fp);
    return written;
}

int main(int argc, char *argv[])
{
    CURL *curl;

    curl_global_init(CURL_GLOBAL_ALL); 
    curl=curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, argv[1]);

    if((fp=fopen(argv[1],”w”))==NULL)
    {
        curl_easy_cleanup(curl);
        exit(1);
    }
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
//CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    exit(0);
}

将收获的html代码存入相应的文本中.看下面一个例证

view plaincopy to clipboardprint?
#include <stdio.h>;   
#include <stdlib.h>;   
#include <unistd.h>;   

#include <curl/curl.h>;   
#include <curl/types.h>;   
#include <curl/easy.h>;   

FILE *fp; //定义FILE类型指针   

size_t write_data(void *ptr, size_t size, size_t nmemb, void
*stream) //这个函数是为顺应CURLOPT_WRITEFUNCTION, 而构造的   
{   
    int written = fwrite(ptr, size, nmemb, (FILE *)fp);   
    return written;   
}   

int main(int argc, char *argv[])   
{   
    CURL *curl;   

    curl_global_init(CURL_GLOBAL_ALL);     
    curl=curl_easy_init();   
    curl_easy_setopt(curl, CURLOPT_URL, argv[1]);     

    if((fp=fopen(argv[1],”w”))==NULL)   
    {   
        curl_easy_cleanup(curl);   
        exit(1);   
    }   
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
//CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理   
    curl_easy_perform(curl);   
    curl_easy_cleanup(curl);   
    exit(0);   

#include <stdio.h>;
#include <stdlib.h>;
#include <unistd.h>;

#include <curl/curl.h>;
#include <curl/types.h>;
#include <curl/easy.h>;

FILE *fp; //定义FILE类型指针

size_t write_data(void *ptr, size_t size, size_t nmemb, void
*stream) //这个函数是为了顺应CURLOPT_WRITEFUNCTION, 而构造的
{
    int written = fwrite(ptr, size, nmemb, (FILE *)fp);
    return written;
}

int main(int argc, char *argv[])
{
    CURL *curl;

    curl_global_init(CURL_GLOBAL_ALL); 
    curl=curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, argv[1]);

    if((fp=fopen(argv[1],”w”))==NULL)
    {
        curl_easy_cleanup(curl);
        exit(1);
    }
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
//CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    exit(0);
}

从ftp站点下载文件的例子.

view plaincopy to clipboardprint?
#include <stdio.h>;   
#include <curl/curl.h>;   
#include <curl/types.h>;   
#include <curl/easy.h>;   

struct FtpFile  
//定义一个构造以传递让my_fwrite函数.可用curl_easy_setopt的CURLOPT_WRITEDATA选项传递   
{   
        char *filename;   
        FILE *stream;   
};   

int my_fwrite(void *buffer, size_t size, size_t nmemb, void
*stream)   
{   
        struct FtpFile *out=(struct FtpFile *)stream; //
stream指针其实就是 指向struct FtpFile ftpfile的   
        if(out && !out->stream)   
        {   
                out->;stream=fopen(out->filename, “wb”);
//没有是流的口舌虽创办一个 名字是out->filename.   
                if(!out->stream)   
                return -1;   
        }   
        return fwrite(buffer, size, nmemb, out->stream);   
}   

int main(int argc, char *argv[])   
{   
        CURL *curl;   
        CURLcode res;   
        struct FtpFile ftpfile={argv[2],NULL};
//初始化一个FtpFile结构    
        curl_global_init(CURL_GLOBAL_DEFAULT);   

        curl = curl_easy_init();   
        if(curl)   
        {   
                curl_easy_setopt(curl, CURLOPT_URL,argv[1]);   
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
my_fwrite);   
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
//给有关函数的季单参数 传递一个结构体的指针   
                curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
//CURLOPT_VERBOSE 这个选项很常用
用来在屏幕及展示对服务器相关操作返回的信   

                res = curl_easy_perform(curl);   
                curl_easy_cleanup(curl);   

                if(CURLE_OK != res)   
                        fprintf(stderr, “curl told us %d\n”,
res);   
        }   
        if(ftpfile.stream)   
        fclose(ftpfile.stream);   
        curl_global_cleanup();   

        return 0;   

#include <stdio.h>;
#include <curl/curl.h>;
#include <curl/types.h>;
#include <curl/easy.h>;

struct FtpFile  
//定义一个构造为传递让my_fwrite函数.可用curl_easy_setopt的CURLOPT_WRITEDATA选项传递
{
        char *filename;
        FILE *stream;
};

int my_fwrite(void *buffer, size_t size, size_t nmemb, void
*stream)
{
        struct FtpFile *out=(struct FtpFile *)stream; //
stream指针其实就是 指向struct FtpFile ftpfile的
        if(out && !out->stream)
        {
                out->;stream=fopen(out->filename, “wb”);
//没有是流的口舌就是创办一个 名字是out->filename.
                if(!out->stream)
                return -1;
        }
        return fwrite(buffer, size, nmemb, out->stream);
}

int main(int argc, char *argv[])
{
        CURL *curl;
        CURLcode res;
        struct FtpFile ftpfile={argv[2],NULL};
//初始化一个FtpFile结构 
        curl_global_init(CURL_GLOBAL_DEFAULT);

        curl = curl_easy_init();
        if(curl)
        {
                curl_easy_setopt(curl, CURLOPT_URL,argv[1]);
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
my_fwrite);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
//给有关函数的季单参数 传递一个结构体的指针
                curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
//CURLOPT_VERBOSE 这个选项很常用
用来当屏幕及亮对服务器相关操作返回的消息

                res = curl_easy_perform(curl);
                curl_easy_cleanup(curl);

                if(CURLE_OK != res)
                        fprintf(stderr, “curl told us %d\n”, res);
        }
        if(ftpfile.stream)
        fclose(ftpfile.stream);
        curl_global_cleanup();

        return 0;
}

速长达实例??显示文件下载快

view plaincopy to clipboardprint?
// 采用CURLOPT_NOPROGRESS, CURLOPT_PROGRESSFUNCTION   
CURLOPT_PROGRESSDATA 实现文件传输进度提示效果   

//函数采用了gtk库,故编译时用点名gtk库   

//函数启动专门的线程用于展示gtk 进度条bar 

#include <stdio.h> 

#include <gtk/gtk.h> 

#include <curl/curl.h> 

#include <curl/types.h> /* new for v7 */ 

#include <curl/easy.h> /* new for v7 */   

GtkWidget *Bar;   

////这个函数是以顺应CURLOPT_WRITEFUNCTION而构造的   

//完成数据保存功能   

size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE
*stream)   

{   

return fwrite(ptr, size, nmemb, stream);   

}   

//这个函数是为顺应CURLOPT_READFUNCTION而构造的   

//数据达传时使用   

size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE
*stream)   

{   

return fread(ptr, size, nmemb, stream);   

}   

//这个函数是为着契合CURLOPT_PROGRESSFUNCTION而构造之   

//显示文件传输速度,t代表文件大小,d代表传输就完结有   

int my_progress_func(GtkWidget *bar,   

                     double t, /* dltotal */ 

                     double d, /* dlnow */ 

                     double ultotal,   

                     double ulnow)   

{   

/* printf(“%d / %d (%g %%)\n”, d, t, d*100.0/t);*/ 

gdk_threads_enter();   

gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);   

gdk_threads_leave();   

return 0;   

}   

void *my_thread(void *ptr)   

{   

CURL *curl;   

CURLcode res;   

FILE *outfile;   

gchar *url = ptr;   

curl = curl_easy_init();   

if(curl)   

{   

    outfile = fopen(“test.curl”, “w”);   

    curl_easy_setopt(curl, CURLOPT_URL, url);   

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);   

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
my_write_func);   

    curl_easy_setopt(curl, CURLOPT_READFUNCTION,
my_read_func);   

    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);   

    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
my_progress_func);   

    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);   

    res = curl_easy_perform(curl);   

    fclose(outfile);   

    /* always cleanup */ 

    curl_easy_cleanup(curl);   

}   

return NULL;   

}   
  

【Curl (libcurl) 开发 】Cocos2dx之libcurl(curl_easy)的编程课程(帮助手册)! | 黑米GameDev街区 – Google Chrome (2013/5/23 14:56:10)

本篇介绍以libcurl编程的一般法以及组成部分主导方法。本文主要是介绍 c 语言的调用接口,同时也恐怕好好的适用于任何类 c 语言的接口。

阳台的可移栽代码

libcurl库背后的开发人员投入了一对一深之大力确保libcurl可以以无数两样的系统与环境里工作。

大局的预备

先后要初始化一些libcurl的全局函数。这意味无论而准备以libcurl多少次,你都当,且仅初始化一次于。当您的次开始之早晚,使用

curl_global_init()

这个函数需要一个参数来报告她什么来初始化。使用CURL_GLOBAL_ALL ,它以为此普通是比好的默认参数来初始化所有都清楚之内部子模块。还有少独可选值:

CURL_GLOBAL_WIN32

这参数就让用在windows 操作系统及。它为libcurl初始化win32法接字的的事物。没有对的初始化,你的次将无可知是的下模拟接字。你应有一味也每个程序召开相同不成这样的操作,如果你的程序的别库这样了,你就无须再次吃libcurl这样做。

CURL_GLOBAL_SSL

夫参数会如libcurl具有SSL的能力。你当就吧每个程序召开同赖这样的操作,如果你的次的其它库这样了,你便绝不还吃libcurl这样做。

libcurl有个默认的保护体制,检测一旦curl_global_init没有在curl_easy_perform之前让调用,那么libcurl会猜测该行使的初始化模式来施行顺序。请小心,依靠默认的保障机制来如此做一些还不好。

当次不再用libcurl,请调用curl_global_cleanup函数来对号入座初始化函数所做的办事,它见面举行逆向的劳作来清理curl_global_init所初始化的资源。

要避免再次的调用curl_global_init和 curl_global_cleanup。他们每个仅被调用一赖。

libcurl所支撑之功效

确定libcurl所提供功能的顶尖方法是在运转的时刻如果未是于编译的早晚。通过调用curl_version_info函数,然后查返回信息之结构体,你懂得当前之libcurl版本所支持之意义了。

以libcurl的简要接口

先是介绍libcurl的概括接口(easy interface),这些接口都发出curl_easy的前缀。 libcurl的近期版还提供了复杂接口(multi interface)。更多涉及该接口的音讯用其他发讨论,为了重新好的晓复杂接口,你还是要事先了解简易接口。

为利用简单接口,你先用创造一个简练接口的句柄。每一个简接口的多少通信都亟需者句柄。一般的话,你待为每个准备传输数据的线程使用一个句柄。但你不用会在多线程里共享相同之句柄。

得到简单句柄

easyhandle = curl_easy_init();

斯函数返回一个简易接人数句柄。接下来的操作力,可以于这`easyhandle设置各种选项。在随后的一个要么数数传中,句柄只是一个逻辑实体。 通过 curl_easy_setopt设置句柄的习性与选,它们控制就的多寡传。这些性与甄选之装置一个保存于句柄里直到她重于安装也外价值。多次大网要使用相同的句柄,它们的句子柄选择以及特性也是一致的。

不少用于安装libcurl属性都是字符串,一个对一段落以0结尾数据。当您用字符串设置 curl_easy_setopt(),libcurl会复制这字符串的一个副本,所以若以安后不用再保存好字符串的内存。

在句柄上最经常设置的性质是URL。你得这么设置它

curl_easy_setopt(handle, CURLOPT_URL, ”http://domain.com/”);

一经你指望取得指定URL上之长距离主机的数码资源及地方。如果你想协调处理获的多少要未是直显示在标准输出里,你可以描绘一个合乎下面原型的函数

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);

乃可据此接近下面这样的代码来控制libcurl将沾的数码传递至您写的函数里

curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);

你还足以控制你的回调函数第四独参数得到的数据,用如此的函数原型

curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);

运这种原型,你可好爱在公程序和为libcurl调用函数之间传递本地数据。使用 CURLOPT_WRITEDATA,libcurl不会见处理你所传递的多寡。

而你没有因此用CURLOPT_WRITEFUNCTION设置回调函数,libcurl会起默认的拍卖。它只是把收到至之数码输出及专业输出里。你可以使用传递一个FILE *的开拓文件参数,设置默认处理函数CURLOPT_WRITEDATA ,它将收获的数量存放于一个文书里。

这里发生一个跟平台有关的先天不足。有时候libcurl不可知操作一个呗程序所打开的文件。如果您用CURLOPT_WRITEDATA于默认的回调函数传递一个打开的公文,程序可能崩溃。(CURLOPT_WRITEDATA 原来的名目也CURLOPT_FILE,它们是一样的办事机理)。

若你因 win32 dll的法使用libcurl,如果您设置了,CURLOPT_WRITEDATA ,也不能不用CURLOPT_WRITEFUNCTION ,否则你见面遇见程序崩溃。 还发另过多之挑三拣四项可以装,我们身处后面还详尽讨论,接着向下看

success = curl_easy_perform(easyhandle);

curl_easy_perform函数将会见接连远程的站点,发送必要的指令和纳传输的数码。当它们接受了数,它便会调用我们原先设置的回调函数。这个函数可能同涂鸦得到一个字节或者几千个字节。libcurl会尽可能多之,尽可能快的传播数据。我们回调函数返回其所得到数码的深浅。如果回去的数目大小及传递给它们多少大小不一致,libcurl将见面停下操作,并返一个错误代码。

当数码传就,curl_easy_perform返回一个代码来告诉你是不是中标。如果您只是返回一个代码还不够,你得下CURLOPT_ERRORBUFFER ,让libcurl缓存许多但读的错误信息

一旦你还想传输其他数,已部分句柄可以屡屡下。记住,鼓励而下现有的语句柄来导其他数据,libcurl会尝试都先已经建立好的连续。

对某些协议,下载文件或者干到不少苛的协议用来记录信息,设置导模式,更改当前之目并最终传递数据。传递一个文本的URL,libcurl会为而掌管所有细节,把公文由同令机器移动至少一模一样大机械。

多线程问题

无限基本的条件是绝对不要以在多独线程之间共享一个libcurl的句柄。确保其他时刻一个句柄只是在一个线程里使用。你得于差不多只线程之间传递句柄,但是你不能够用。

libcurl是线程安全之,除了以下简单种植情景:信号量和SSL/TLS词柄。信号量用于超时失效名字解析(在域名解析的时)。

假若你通过多线程方式来聘HTTPS 或者 FTPS 网址,你可以使用底层的SSL库,多线程库。这些库或者产生其独有的求,你若多加留心详细参考

OpenSSL

http://www.openssl.org/docs/crypto/threads.html\#DESCRIPTION

GnuTLS

http://www.gnu.org/software/gnutls/manual/html\_node/Multi\_002dthreaded-applications.html

NSS 它宣称是线程安全,没有任何异常的要求。 PolarSSL 未知。yassl 未知。axTLS 未知。

当您用多线程的下,你当也有着的句子柄设置CURLOPT_NOSIGNAL 选项。所有的时刻还可以干活正常除了DNS查询过的早晚。 同样,CURLOPT_DNS_USE_GLOBAL_CACHE 也无是线程安全之。

当libcurl实际无法工作

老是发生各种原因促成网络传输失败。你恐怕设置错误的libcurl选项,误解了libcurl某些选项之实际上作用,或者远程服务器返回libcurl一个非标准的对。

当有误的当儿,这里发生一个黄金法:设置CURLOPT_VERBOSE 选项也1。这将致libcurl显示有富有发送的实体协议的底细,或者还有一些之中的音信及一些收协议的数据(尤其是 FTP)。如果你用HTTP ,CURLOPT_HEADER设为1,请求头/响应头也会见为输出,这些头信息将现出在消息的内容遭。

如果CURLOPT_VERBOSE 还不够,你设置CURLOPT_DEBUGFUNCTION来调节你的多寡。

上传数据到长途站点

libcurl尽量保持和协商无关性,就是上传文件及长途的FTP跟用PUT方式上污染数据到HTTP服务器和坏类似之。 我们写一个序,很可能想libcurl按照我们的渴求及污染数据。我急需装如下函数原型的朗读数据的回调函数

size_t function(char *bufptr, size_t size, size_t nitems, void *userp);

bufptr 参数指为同一截准备上传数据的缓冲区,nitem是马上段缓冲区的轻重缓急,userp是一个用户从定义指针,libcurl不对准拖欠指针作其他操作,它只是略的传递该指针。可以使该指针在应用程序与libcurl之间传递信息。

curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_function);
curl_easy_setopt(easyhandle, CURLOPT_READDATA, &filedata);
Tell libcurl that we want to upload:
curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1L);

来几乎单协议将非克健康办事当上传的时节从不报告上传文件的轻重缓急。所以设置及污染文书之大大小小要以CURLOPT_INFILESIZE_LARGE

/* in this example, file_size must be an curl_off_t variable */
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);

当你调用curl_easy_perform()的上,libcurl会执行有的必不可少动作,当起上传的时段,它会调用我的回调函数。程序会尽可能多,尽可能快之底上传数据。回调函数返回写副缓冲区的数量的分寸。返回0的早晚就是象征达成传了了。

密码

过剩协议要求用户称和密码才会下载或上污染你所选取的多寡。libcurl提供了指定的几种方式。

许多商还支持用户称及密码包含在指定的URL里。libcurl会检测并相应的施用它。可以按照这样的格式写

protocol://user:password@example.com/path/

万一您的用户称和密码要有好奇之字符,你应有利用URLd编码,像%XX,其中XX是个别位十六进制的数字。

libcurl同事呢提供了一个设置各种类型密码的选项项。设置CURLOPT_USERPWD 选项如下

curl_easy_setopt(easyhandle, CURLOPT_USERPWD, ”myname:thesecret”);

在少数情况下或者会见一再行使用户称与密码,可以应用代码来验证身份。libcurl提供一个CURLOPT_PROXYUSERPWD选项来实现这种效果,跟CURLOPT_USERPWD 选项大类似

curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, ”myname:thesecret”);

HTTP 认证

早先的段我们展示了争为要证实的URL设置用户以及密码。当我们采取HTTP协议的下,客户端起许多两样之朝服务器发送身份验证。最基本的HTTP认证为Basic认证,它发送base64编码的公然用户与密码,这不安全。 如今,libcrul支持下Basic, Digest, NTLM, Negotiate, GSS-Negotiate and SPNEGO等方式的辨证,你可以设置CURLOPT_HTTPAUTH 告诉libcurl使用那种认证。

curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

当您想代理服务器认证的下,你得下

CURLOPT_PROXYAUTH:

curl_easy_setopt(easyhandle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);

而可整合又证方式,libcurl会以合理的方法处理 curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC);

以方便起见,你还得利用CURLAUTH_ANY,它同意libcurl使用外想如果的主意。

HTTP POST

HTML最简便易行的也是不过普遍的POST是利用<form>这个标签来落实之。我们提供了一个对准数据段 指针,然后告诉licurl把其发送至长途站点:

char *data=”name=daniel&project=curl”;
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(easyhandle, CURLOPT_URL, ”http://posthere.com/”);

curl_easy_perform(easyhandle); /* post away! */

是未是老大简单。当您设置了CURLOPT_POSTFIELDS选项,它会自动切换句柄来POST接下的请求。

倘你想发送二进制的数目,需要设置一下数据头,用来名数据的门类以及数量的大小。如下

struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, ”Content-Type: text/xml”);

/* post binary data */
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, binaryptr);

/* set the size of the postfields data */
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23L);

/* pass our list of custom made headers */
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);

curl_easy_perform(easyhandle); /* post away! */

curl_slist_free_all(headers); /* free the header list */

还有平等栽是multi-part 表单提交,这被认为是平等种植更好之计提交二进制的数。libcrul同样为支持这种办法。下面是例证:

struct curl_httppost *post=NULL;
struct curl_httppost *last=NULL;
curl_formadd(&post, &last,   CURLFORM_COPYNAME, ”name”,   CURLFORM_COPYCONTENTS, ”daniel”, CURLFORM_END);
curl_formadd(&post, &last,   CURLFORM_COPYNAME, ”project”,   CURLFORM_COPYCONTENTS, ”curl”, CURLFORM_END);
curl_formadd(&post, &last,   CURLFORM_COPYNAME, ”logotype-image”,   CURLFORM_FILECONTENT, ”curl.png”,
CURLFORM_END);

/* Set the form info */
curl_easy_setopt(easyhandle, CURLOPT_HTTPPOST, post);

curl_easy_perform(easyhandle); /* post away! */

/* free the post data again */
curl_formfree(post);

libcurl还允许你在每个定义的组成部分设置头。下面就例证

struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, ”Content-Type: text/xml”);

curl_formadd(&post, &last,   CURLFORM_COPYNAME, ”logotype-image”,   CURLFORM_FILECONTENT, ”curl.xml”,
CURLFORM_CONTENTHEADER, headers,   CURLFORM_END);

curl_easy_perform(easyhandle); /* post away! */

curl_formfree(post);
/* free post */
curl_slist_free_all(headers);
/* free custom header list */

负有对简易接人句柄都是”粘的”,这些属于性会一直保持无换除非你当调用 curl_easy_perform之前改了。通过将CURLOPT_HTTPGET设为1可要简单接人词柄回到最老的状态:

curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);

只设置CURLOPT_POSTFIELDS 的无非吗””或者NULL是勿会见告一段落libcurl做POST请求的,这就见面开提交空数据的POST。

来得速度

通过将CURLOPT_NOPROCESS设置也0发端起来进度支持。该选项默认值为1。对绝大多数应用程序,我们得提供一个速度显示回调。libcurl会不期的用眼前导的进度通过回调函数告诉你的主次。

//回调函数原型
int progress_callback(void *clientp,   double dltotal,
double dlnow,   double ultotal,   double ulnow);

/*通过CURLOPT_PROGRESSFUNCTION注册该回调函数。
参数clientp是一个用户从定义指针,应用程序通过CURLOPT_PROCESSDATA
性将该自定义指定传递让libcurl。libcurl对拖欠参数不发其它处理,
只是简短以其传递给回调函数。*/

libcurl和c++

仅仅发生相同码用特别注意的是回调函数不可知而类似的非静态成员函数。如

class AClass
{
static size_t write_data(void *ptr, size_t size, size_t nmemb,
void *ourpointer)
{
/* do what you want with the data */
}
}

代理

略过,有趣味请参见原文。

持久化的便宜

当需要发送多次伸手时,应该重复使用easy handle。

历次执行完curl_easy_perform,licurl会继续保障与服务器的接连。接下来的乞求可以应用这连续而不要创建新的连续(如果目标主机是和一个以来)。这样好抽网络支出。 即使连续于放走了,libcurl也会见缓存这些连的对话信息,这样下次再也连至目标主机上时常,就可以以这些消息,从而减少重复连接所待的年华。

FTP连接可能会见于封存于丰富的日。因为客户端要跟FTP服务器进行频繁之一声令下交互。对于有看人数上限的FTP服务器,保持一个添加连,可以假设你不欲排除等,就直可以跟FTP服务器通信。

libcurl会缓存DNS的辨析结果。

在随后底libcurl版本中,还见面补加有特点来提高数据通信的频率。 每个简单接人数词柄都见面保留最近采用的几乎单连续,以统重用。默认是5只。可以经过CURLOPT_MAXCONNECTS属性来安保存连接的数据。

苟您免思量引用连接,将CURLOPT_FRESH_CONNECT属性设置为1。这样每次交请求时,libcurl都见面先行关以前创建的连天,然后又创设一个初的连日。也足以拿CURLOPT_FORBID_REUSE设置也1,这样每次执行完毕要,连接就会见即时关闭。

libcurl使用HTTP消息头

当使用libcurl发送http请求时,它会活动抬高一些http头。我们得以经过CURLOPT_HTTPHEADER属性手动替换、添加或去相应的HTTP消息头。

不同:以POST的法子为HTTP服务器交由请求时,libcurl会设置该消息头为”100-continue”,它要求服务器在标准拍卖该要之前,返回一个”OK”消息。如果POST的多寡好有点,libcurl可能不见面设置该消息头。

起定义的操作

现阶段更进一步多之情商还构建以HTTP协议之上(如:soap),这主要归功给HTTP的可靠性,以及为大面积利用的代理支持(可以穿透大部分防火墙)。 这些协议的用办法以及习俗HTTP可能发充分酷的不等。对是,libcurl作了异常好之支撑。

cookies

cookie是一个键值对之集,HTTP服务器发给客户端的cookie,客户端提交请求的当儿,也会用cookie发送及服务器。服务器可以因cookie来跟用户之对话信息。cookie有过时,超时后cookie就会见失效。cookie有域名及路径限制,cookie只能发给指定域名和路的HTTP服务器。

于libcurl中,可以经CURLOPT_COOKIE属性来设置发于服务器的cookie:

curl_easy_setopt(easyhandle, CURLOPT_COOKIE, ”name1=var1; name2=var2;”);

于其实的应用场景中,你可能用保留服务器发送给你的cookie,并以联网下的请被,把这些cookie一并作朝服务器。所以,可以将上次于服务器收到的富有响应头信息保存至文本文件中,当下次要为服务器发送请求时,通过CURLOPT_COOKIEFILE属性告诉libcurl从该文件被读取cookie信息。 设置CURLOPT_COOKIEFILE属性意味着激活libcurl的cookie parser。在cookie parser被激活之前,libcurl忽略用前面收到至的cookie信息。cookie parser被激活后,cookie信息将吃保留内存中,在连下去的要被,libcurl会自动将这些cookie信息上加至消息头里,你的应用程序不需要做其他事件。大多数动静下,这都够用了。需要小心的是,通过CURLOPT_COOKIEFILE属性来激活cookie parser,给CURLOPT_COOKIEFILE属性设置的一个保留cookie信息之公文文件路径,可能并不需要在磁盘上物理存在。 如果你需要利用NetScape或者FireFox浏览器的cookie文件,你若用这些浏览器的cookie文件之路径来初始化CURLOPT_COOKIEFILE属性,libcurl会自动分析cookie文件,并当对接下的请过程遭到应用这些cookie信息。 libcurl甚至能够把接受至之cookie信息保存成会为Netscape/Mozilla的浏览器所识别的cookie文件。通过将这些号称cookie-jar。通过安装CURLOPT_COOKIEJAR选项,在调用curl_easy_cleanup释放easy handle的下,所有的这些cookie信息还见面保留至cookie-jar文件中。这就是使得cookie信息能够在不同之easy handle甚至于浏览器之间实现共享。

curl使用笔记 | 大鱼儿@Live – Google Chrome (2013/5/22 15:34:11)

curl使用笔记

CURLOPT_HEADER:设为1,则当回去的情里噙http header;

 

CURLOPT_FOLLOWLOCATION:设为0,则未见面活动301,302超越反;

 

*CURLOPT_INFILESIZE:
当你达到传一个文件及长途站点,这个选项告诉PHP你上传文书的高低。

*CURLOPT_VERBOSE:
如果你想CURL报告每一样项奇怪之事务,设置这个选项也一个非零值。

*CURLOPT_HEADER:
如果你想管一个峰包含在出口中,设置是选项也一个非零值。

*CURLOPT_NOPROGRESS:
如果您无见面PHP为CURL传输显示一个经过条,设置是选项也一个非零值。

 

在意:PHP自动装是选项为非零值,你应该就为调节的目的来改是选项。

 

*CURLOPT_NOBODY:
如果你免思量当出口中涵盖body部分,设置是选项也一个非零值。

*CURLOPT_FAILONERROR:
如果你想给PHP在生误(HTTP代码返回大于等于300)时,不显得,设置是选项也平人口不零值。默认行为是返一个好端端页,忽略代码。

*CURLOPT_UPLOAD:
如果您想给PHP为直达污染做准备,设置这个选项也一个非零值。

*CURLOPT_POST: 如果您想PHP去举行一个规范的HTTP
POST,设置这个选项也一个非零值。这个POST是日常的
application/x-www-from-urlencoded 类型,多数给HTML表单使用。

*CURLOPT_FTPLISTONLY:
设置这个选项为非零值,PHP将列有FTP的目名列表。

*CURLOPT_FTPAPPEND:
设置这个选项也一个非零值,PHP将祭远程文件替代覆盖其。

*CURLOPT_NETRC: 设置是选项也一个非零值,PHP将当公的 ~./netrc
文件被搜索你如果建立连接的长途站点的用户名及密码。

*CURLOPT_FOLLOWLOCATION: 设置这个选项也一个非零值(象 “Location:
“)的峰,服务器会管其作为HTTP头的平等组成部分发送(注意及时是递归的,PHP将发送形如
“Location: “的腔)。

 

*CURLOPT_PUT:
设置是选项也一个非零值去用HTTP上传一个文本。要高达污染是文件要安装CURLOPT_INFILE和CURLOPT_INFILESIZE选项.

*CURLOPT_MUTE: 设置是选项也一个非零值,PHP对于CURL函数将完全沉默。

*CURLOPT_TIMEOUT: 设置一个长整形数,作为最酷累多少秒。

*CURLOPT_LOW_SPEED_LIMIT: 设置一个长整形数,控制传送多少字节。

*CURLOPT_LOW_SPEED_TIME:
设置一个长整形数,控制多少秒传送CURLOPT_LOW_SPEED_LIMIT规定之字节数。

*CURLOPT_RESUME_FROM:
传递一个含字节偏移地址的增长整形参数,(你想换至之开端表单)。

*CURLOPT_SSLVERSION:
传递一个分包SSL版本的丰富参数。默认PHP将受它和谐拼命的确定,在更多之安康被若要手工安装。

*CURLOPT_TIMECONDITION:
传递一个添加参数,指定怎么处理CURLOPT_TIMEVALUE参数。你可以设置是参数为

TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。这不过用于HTTP。

*CURLOPT_TIMEVALUE:
传递一个起1970-1-1发端至今之秒数。这个时空将吃CURLOPT_TIMEVALUE选项作为指定值使用,或吃默认

TIMECOND_IFMODSINCE使用。

 

下列选项之值将受作为字符串:

 

*CURLOPT_URL:
这是你想用PHP取回之URL地址。你也可当为此curl_init()函数初始化时设置是选项。

*CURLOPT_USERPWD:
传递一个形如[username]:[password]作风的字符串,作用PHP去老是。

*CURLOPT_PROXYUSERPWD: 传递一个形如[username]:[password]
格式的字符串去老是HTTP代理。

*CURLOPT_RANGE:
传递一个而想指定的克。它应该是”X-Y”格式,X或Y是吃除外的。HTTP传送同样支撑几只区间,用逗句来划分隔(X-Y,N-M)。

*CURLOPT_POSTFIELDS: 传递一个当做HTTP “POST”操作的有着数据的字符串。

*CURLOPT_REFERER: 在HTTP请求中含有一个”referer”头的字符串。

*CURLOPT_USERAGENT: 在HTTP请求中蕴藏一个”user-agent”头的字符串。

*CURLOPT_FTPPORT: 传递一个涵盖被ftp
“POST”指令以的IP地址。这个POST指令告诉远程服务器去老是我们指定的IP地址。
这个字符串可以是一个IP地址,一个主机名,一个网络界面名(在UNIX下),或是‘-’(使用系统默认IP地址)。

*CURLOPT_COOKIE: 传递一个富含HTTP cookie的峰连续。

*CURLOPT_SSLCERT: 传递一个涵盖PEM格式证书之字符串。

*CURLOPT_SSLCERTPASSWD:
传递一个含使用CURLOPT_SSLCERT证书必需的密码。

*CURLOPT_COOKIEFILE:
传递一个蕴含cookie数据的文书之名字的字符串。这个cookie文件可以是Netscape格式,或是堆有文件中之HTTP风格的头。

*CURLOPT_CUSTOMREQUEST:
当进行HTTP请求时,传递一个字符被GET或HEAD使用。为开展DELETE或外操作是有利之,更Pass
a string to be used instead of GET or HEAD when doing an HTTP request.
This is useful for doing or another, more obscure, HTTP request.

专注: 在确认你的服务器支持命令先不若错过这样做。

下列的选项要求一个文书讲述(通过采取fopen()函数获得):

*CURLOPT_FILE: 这个文件将是您放传送的输出文件,默认是STDOUT.

*CURLOPT_INFILE: 这个文件是你传送过来的输入文件。

*CURLOPT_WRITEHEADER: 这个文件写有您输出的条片。

*CURLOPT_STDERR: 这个文件写起左而休是stderr。

 

 

 

 

 

 

libcurl 凡是一个雅不错的仓库,支持http,ftp等许多之合计。使用库太老之体会就是,不细心看文档,仅仅看在例子就是写序,是相同起危险的工作。我之次第崩溃了,我怀疑是和谐代码写的题目,后来意识是堆栈没因此对。不密切看文档(有时候文档本身吗比差劲,这时除了看仔细外,还要多动脑子,考虑其是怎么落实之),后果非常严重。不加思索的用他人的仓库或者代码,有时候很好听,但是出题目常常,却是浮动的。

1. CURLcode
curl_global_init(long flags);
在差不多线程应用中,需要在主线程遭遇调用这个函数。这个函数设置libcurl所急需的环境。通常情况,如果非显式的调用它,第一不善调动用curl_easy_init()时,curl_easy_init
会调用
curl_global_init,在单线程环境下,这不是题材。但是多线程下就杀了,因为curl_global_init不是线程安全之。在差不多个线程中调用curl_easy_int,然后如果少只线程同时发现curl_global_init还尚未给调用,同时调用curl_global_init,悲剧就发生了。这种情形有的几率很有些,但可能是存在的。

2.
libcurl
有只可怜好的表征,它甚至足以操纵域名解析的超时。但是当默认情况下,它是运alarm

  • siglongjmp
    实现的。用alarm在差不多线程下做过,本身便几乎不容许。如果只是使用alarm,并无会见招致程序崩溃,但是,再加上siglongjmp,就设命矣(程序崩溃的坏可怕,core中几乎看不闹有因此信息),因为其需要一个sigjmp_buf型的全局变量,多线程修改它。(通常情况下,可以每个线程一个
    sigjmp_buf 型的变量,这种景象下,多线程中利用 siglongjmp
    是未曾问题的,但是libcurl只出一个全局变量,所有的线程都见面为此)。

 
具体是看似 curl_easy_setopt(curl, CURLOPT_TIMEOUT,
30L)
的过设置,导致alarm的采用(估计有在域名解析阶段),如前所述,这在差不多线程中凡是大的。解决智是剥夺掉alarm这种超时,
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L)。

 
这样,多线程中行使过就高枕无忧了。但是域名解析就从来不了过机制,碰到很缓慢的域名解析,也非常辛苦。文档的提议是 Consider building libcurl with
c-ares support to enable asynchronous DNS lookups, which enables nice
timeouts for name resolves without signals.  c-ares 是异步的 DNS 解决方案。

来源: <http://gcoder.blogbus.com/logs/54871550.html>

 

curl_slist_append()
函数声称如下:

?

1
2
#include <curl/curl.h>
struct curl_slist *curl_slist_append(struct curl_slist * list, const char * string );

欠函数将一个字符串追加到
slist 链表中。第 1 个参数是 struct_slist 类型链表;第 2
只参数是要是增加至链表节点结构面临的字符串。函数完成后,返回指于该链表的指针。

struct
curl_slist 的类型定义在 curl.h 中:

?

1
2
3
4
5
/* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist {
  char *data;
  struct curl_slist *next;
};

下了该函数,在劳作就后应采取 curl_slist_free_all() 对那个链表进行释放。

来源: <http://www.groad.net/bbs/read.php?tid-3985.html>

 

 

 

curl/types.h: No such file or directory问题的化解

公布时: 2012-08-27 09:49    来源: blog.csdn.net 

以程序中因故到了libcurl,编译时出现

curl/types.h: No such file or directory错误

查找到http://projects.springlobby.info/issues/1575中提到了这个问题

This is a problem on archlinux which just got curl 7.21.7.

curl devs removed curl/types.h and put its content in curl/curl.h.

意思是以新版中把curl/types.h合并及了curl/curl.h中

自己的缓解措施是于

[plain] view
plaincopy

  1. cd /usr/include/curl/  
  2. sudo ln -s curl.h types.h  

再度编译,问题无了。

来源: <http://www.eifr.com/article.php?id=1800>

 

linux curl命令详解 – – ITeye技术网站 – Google Chrome (2013/5/22 15:31:00)

linux curl命令详解

  • linux

LinuxPHPCC++C# 

个体技术博客:http://demi-panda.com

 

一样、参数详解

 -M/–manual  显示全手动
 -n/–netrc  从netrc文件中读取用户名和密码
 –netrc-optional  使用 .netrc 或者 URL来覆盖-n
 –ntlm  使用 HTTP NTLM 身份验证
 -N/–no-buffer  禁用缓冲输出
 -o/–output  把输出写到该文件中
 -O/–remote-name  把输出写到该文件中,保留远程文件的文件名
 -p/–proxytunnel  使用HTTP代理
 –proxy-anyauth  选择任一代理身份验证方法
 –proxy-basic  在代理上使用基本身份验证
 –proxy-digest  在代理上使用数字身份验证
 –proxy-ntlm  在代理上使用ntlm身份验证
 -P/–ftp-port <address>  使用端口地址,而不是使用PASV
 -Q/–quote <cmd>  文件传输前,发送命令到服务器
 -r/–range <range>  检索来自HTTP/1.1或FTP服务器字节范围
 –range-file    读取(SSL)的随机文件
 -R/–remote-time  在本地生成文件时,保留远程文件时间
 –retry <num>  传输出现问题时,重试的次数
 –retry-delay <seconds>  传输出现问题时,设置重试间隔时间
 –retry-max-time <seconds>  传输出现问题时,设置最大重试时间
 -s/–silent  静音模式。不输出任何东西
 -S/–show-error  显示错误
 –socks4 <host[:port]>  用socks4代理给定主机和端口
 –socks5 <host[:port]>  用socks5代理给定主机和端口
 -t/–telnet-option <OPT=val>  Telnet选项设置
 –trace <file>  对指定文件进行debug
 –trace-ascii <file> Like  跟踪但没有hex输出
 –trace-time  跟踪/详细输出时,添加时间戳
 -T/–upload-file <file>  上传文件
 –url <URL>  Spet URL to work with
 -u/–user <user[:password]>  设置服务器的用户和密码
 -U/–proxy-user <user[:password]>  设置代理用户名和密码
 -V/–version  显示版本信息
 -w/–write-out [format]  什么输出完成后
 -x/–proxy <host[:port]>  在给定的端口上使用HTTP代理
 -X/–request <command>  指定什么命令
 -y/–speed-time  放弃限速所要的时间。默认为30
 -Y/–speed-limit  停止传输速度的限制,速度时间’秒
 -z/–time-cond  传送时间设置
 -0/–http1.0  使用HTTP 1.0
 -1/–tlsv1  使用TLSv1(SSL)
 -2/–sslv2  使用SSLv2的(SSL)
 -3/–sslv3  使用的SSLv3(SSL)
 –3p-quote   like -Q for the source URL for 3rd party transfer
 –3p-url  使用url,进行第三方传送
 –3p-user  使用用户名和密码,进行第三方传送
 -4/–ipv4  使用IP4
 -6/–ipv6  使用IP6
 -#/–progress-bar  用进度条显示当前的传送状态

二,常用curl实例 

1,抓取页面内容到一个文件中
[root@10.10.90.97 ~]# curl -o home.html  http://www.sina.com.cn 

2,用-O(大写的),后面的url要具体到某个文件,不然抓不下来。我们还可以用正则来抓取东西 
[root@10.10.90.97 ~]# curl -O http://www.it415.com/czxt/linux/25002_3.html 

3,模拟表单信息,模拟登录,保存cookie信息 
[root@10.10.90.97 ~]# curl -c ./cookie_c.txt -F log=aaaa -F pwd=****** http://blog.51yip.com/wp-login.php
 
4,模拟表单信息,模拟登录,保存头信息 
[root@10.10.90.97 ~]# curl -D ./cookie_D.txt -F log=aaaa -F pwd=****** http://blog.51yip.com/wp-login.php
 
-c(小写)产生的cookie和-D里面的cookie是不一样的。
5,使用cookie文件 
[root@10.10.90.97 ~]# curl -b ./cookie_c.txt  http://blog.51yip.com/wp-admin 

6,断点续传,-C(大写的)
[root@10.10.90.97 ~]# curl -C -O http://www.sina.com.cn 

7,传送数据,最好用登录页面测试,因为你传值过去后,curl回抓数据,你可以看到你传值有没有成功 
[root@10.10.90.97 ~]# curl -d log=aaaa  http://blog.51yip.com/wp-login.php 

8,显示抓取错误 
[root@10.10.90.97 ~]# curl -f http://www.sina.com.cn/asdf 
curl: (22) The requested URL returned error: 404
[root@10.10.90.97 ~]# curl http://www.sina.com.cn/asdf 
<HTML><HEAD><TITLE>404,not found</TITLE>
。。。。。。。。。。。。
9,伪造来源地址,有的网站会判断,请求来源地址 
[root@10.10.90.97 ~]# curl -e http://localhost http://www.sina.com.cn 
10,当我们经常用curl去搞人家东西的时候,人家会把你的IP给屏蔽掉的,这个时候,我们可以用代理 
[root@10.10.90.97 ~]# curl -x 10.10.90.83:80 -o home.html http://www.sina.com.cn 
11,比较大的东西,我们可以分段下载
[root@10.10.90.97 ~]# curl -r 0-100 -o img.part1 http://i2.f.itc.cn/thumb/180/bj/6018/b_60178154.jpg 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   101  100   101    0     0   1926      0 –:–:– –:–:– –:–:–     0
[root@10.10.90.97 ~]# curl -r 100-200 -o img.part2 http://i2.f.itc.cn/thumb/180/bj/6018/b_60178154.jpg 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   101  100   101    0     0   3498      0 –:–:– –:–:– –:–:–   98k
[root@10.10.90.97 ~]# curl -r 200- -o img.part3 http://i2.f.itc.cn/thumb/180/bj/6018/b_60178154.jpg     
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 13515  100 13515    0     0   154k      0 –:–:– –:–:– –:–:–  280k
[root@10.10.90.97 ~]# ll |grep img.part
-rw-r–r– 1 root root   101 Jan 24 10:59 img.part1
-rw-r–r– 1 root root   101 Jan 24 11:00 img.part2
-rw-r–r– 1 root root 13515 Jan 24 11:00 img.part3
用的时候,把他们cat一下就OK了,cat img.part* >img.jpg
12,不显示下载进度信息
[root@10.10.90.97 ~]# curl -s -o aaa.jpg  
13,显示下载进度条 
[root@10.10.90.97 ~]# curl -# -O  http://www.it415.com/czxt/linux/25002_3.html 
######################################################################## 100.0%
14,通过ftp下载文件 
[root@10.10.90.97 ~]# curl -u 用户名:密码 -O http://blog.51yip.com/demo/curtain/bbstudy_files/style.css 
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
101  1934  101  1934    0     0   3184      0 –:–:– –:–:– –:–:–  7136
或者用下面的方式
[root@10.10.90.97 ~]# curl -O ftp://xukai:test@192.168.242.144:21/www/focus/enhouse/index.php 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 87518  100 87518    0     0  2312k      0 –:–:– –:–:– –:–:– 11.5M
15,通过ftp上传 
[root@10.10.90.97 ~]# curl -T xukai.php ftp://xukai:test@192.168.242.144:21/www/focus/enhouse/         
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 87518    0     0  100 87518      0  2040k –:–:– –:–:– –:–:– 8901k

null

相关文章