ACCESS笔记整理–LibCurl开发

Linux libcurl使用(一)(收藏)_留风的贝壳_百度空间 – 谷歌 Chrome (201五分三/贰叁 一5:一柒:0一)

cU猎豹CS陆L 的起点与进步

cU福特ExplorerL 是 丹尼尔勒 Stenberg 发明的,不过 600
多名开发人士也做出了高大的孝敬。它无疑是多多益善应用程序都使用的有用技术之1。

cU福特ExplorerL 最初的安排性初衷是选取差异的协议(比如 FTP、HTTP、SCP
等)在端点之间活动文件。它最初是3个指令行实用工具,但今天也是一个绑定了
30 三种语言的库。因而,未来不只好够通过 shell 使用
cURubiconL,您还足以创设统一了这么些重点成效的应用程序。libcurl
库也是能够移植的,援救 Linux®、IBM®AIX®操作系统、BSD、Solaris
以及众多任何 UNIX®变体。

回页首

拿到和设置
cU汉兰达L/libcurl

收获和设置 libcurl 格外不难,取决于你所运转的 Linux 发行版。要是运营的是
Ubuntu,您能够应用 apt-get轻松安装那些包。以下行演示了如何为
libcurl 安装 libcurl 和 Python 绑定:

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

apt-get实用工具确定保证该进程满意全数的正视性关系。

回页首

在指令行中使用 cU牧马人L

cUSportageL 最初始是3个命令行工具,能够使用 Uniform Resource Locator (U中华VL)
语法执行多少传输。思量到它在命令行上的流行度,后来创设了三个足以在应用程序中生成那个作为的库。近来,命令行
cU凯雷德L 是 cU中华VL 库的包装器。本文首先商讨 cUTucsonL
作为命令行的成效,然后深刻商量怎么着将它看成库使用。

cU中华VL 的三种常见用法是采纳 HTTP 和 FTP 协议实行理文件件传输。cUHummerH二L
为这一个协议提供3个差不离的接口。要利用 HTTP 从网站取得文件,只需告诉 cU讴歌MDXL
您要将网页写入到里面包车型客车地方文件的文书名、网站的 U景逸SUVL
以及要获得的文本。让我们看一下清单 一 中的不难命令行示例。

清单 一. 接纳 cUEvoqueL 从网址取得文件的以身作则

                
 $ 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)。要动用
cU奥迪Q5L 将该文件移动到 FTP 站点,能够选择 -T选拔钦命要上传的公文,然后提供
FTP 站点的 U中华VL 以及文件的门道。

清单 二. 施用 cU本田UR-VL 将文件上传到 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 
 $ 

是还是不是不会细小略?学习了有个别形式之后你会发觉,cUPRADOL
使用起来相当简单。不过你能够动用的选项13分多 —在 cU普拉多L
命令行中请求增派(使用 --help)能够赢得 12玖行选项。倘若你觉得那还不算太多,那么还有一大批判别的控制选项(从详细度到安全性),以及特定于商业事务的安顿项。

从开发人士的角度看,那还不算是 cU陆风X8L 最令人高兴的地点。让我们深刻摸底
cU福睿斯L 库,学习怎么向应用程序添Gavin件传输协议。

回页首

作为库的 cUHummerH二L

设若你有 10年以上的脚本语言经验,您就会专注到它们的记号有非常大的更动。Python、Ruby、Perl
等那几个脚本语言不仅带有套接字层(C 或 C++ 中也有),还含有了应用层协议
API。那几个脚本语言合并了尖端功用,能够成立 HTTP 服务器或客户端。libcurl
库为 C 和 C++
之类的语言添加了看似的机能,不过它能够在分裂的语言之间移植。在拥有它帮助的言语中都能找到与
libcurl 相当的作为,可是由于那一个语言的出入极大(设想一下 C 和
Scheme),提供那一个行为的主意也很不等同。

libcurl 库以 API 的格局部封闭疗法装清单 1和清单 2中讲述的行事,因而它能够被高级语言应用(近日已超过30 种)。本文提供了 libcurl 的八个示范。第1个示范钻探采纳 c 创设的简练
HTTP 客户端(适合创设 Web 爬行器),第二个示范是2个应用 Python
创设的简约 HTTP 客户端。

回页首

基于 C
的 HTTP 客户端

C API 在 libcurl 功用上提供了多少个 API。easy 接口是多少个简练的联名API(意味着当您使用请求调用 libcurl
时,将能够满意你的伏乞,直到完毕或发生错误)。多接口可以特别控制
libcurl,您的应用程序能够实施几个协同传输,并操纵 libcurl
哪一天哪里活动多少。

该示例使用 easy 接口。该 API
还是能控制数据移动进度(使用回调),但正如其名目所示,使用起来卓殊不难。清单
三 提供了 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文件,包含 cU陆风X8L
根文件。接下来,我定义了五个用于传输的变量。第一个变量是 wr_buf,表示将在其间写入传入数据的缓冲区。wr_index意味着缓冲区的此时此刻写入索引。

转到 main函数,该函数使用
easy API 实行设置。全部 cURL
调用都通过拥戴特定请求状态的句柄实行操作。那名字为 CURL指南针引用。本例还创制贰个奇特的重临码,称为 CURLcode。在应用别的 libcurl
函数在此以前,您必要调用 curl_easy_init获取 CURL句柄。接下来,注意 curl_easy_setopt调用的多寡。它们为一定的操作配置句柄。对于这一个调用,您提供句柄、命令和选拔。首先,本例使用CURLOPT_URL钦点要得到的
U猎豹CS陆L。然后,它应用 CURL_WRITEDATA提供三个上下文变量(在本例中,它是中间的
write 错误变量)。最终,它使用 CURLOPT_WRITEFUNCTION点名数量可用时应当调用的函数。在运转API 之后,API 将使用它读取的数量数次调用该函数。

要起先传输,调用 curl_easy_perform。它的工作是依照此前的布局执行传输。调用该函数时,在做到传输或发生错误从前该函数不会回来。main的末梢一步是交由重返状态,提交页面读取,最终动用 curl_easy_cleanup扫除(当使用句柄执行完操作后)。

近来看望 write_data函数。该函数是指向一定操作收到多少时调用的回调。注意,当你从网址读取数据时,将写入该数额(write_data)。将向回调提供3个缓冲区(包蕴可用数据)、成员数量和尺寸(缓冲中可用数据总量)、上下文指针。第四个任务是保险缓冲区(wr_buf)的半空中可以写入数据。即使不够,它将设置上下文指针并赶回
0,表示出现难题。不然,它将 cU猎豹CS6L
缓冲区的数据复制到您的缓冲区,并增添索引,指向要写入的下三个义务。本例还停止字符串,稍后能够对其利用 printf。最终,它回到 libcurl
操作的字节数量。那将告诉 libcurl
数据被提取,它也能够放任该数量。那正是从网址将文件读取到内部存款和储蓄器的周旋简便易行的诀窍。

回页首

基于
Python 的 HTTP 客户端

本节提供的演示类似于依照 C 的 HTTP 客户端,不过它应用的是 Python。Python
是壹种非凡实用的面向对象的脚本语言,在原型化和营造生产软件方面10分优秀。示例假若您较熟习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) 

Linux libcurl使用(一)(收藏)

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

Linux   二〇〇玖-10-20 一3: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程序都要选取它。

二.二 主要函数

1.CURLcode curl_global_init(long flags);

描述:
那些函数只好用1遍。(其实在调用curl_global_cleanup 函数后仍然可再用)
假使这些函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动完结。
参数:flags
CURL_GLOBAL_ALL                      //开首化全部的或是的调用。
CURL_GLOBAL_SSL                      //初阶化帮衬 保险套接字层。
CURL_GLOBAL_WIN3二            //开端化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用来开始化一个CU纳瓦拉L的指针(有些像再次回到FILE类型的指针壹样).
相应的在调用甘休时要用curl_easy_cleanup函数清理.
一般curl_easy_init意味着3个会话的起初.
它的重回值一般都用在easy连串的函数中.
5 void curl_easy_cleanup(CURL *handle);
描述:
其一调用用来截止三个会话.与curl_easy_init同盟着用. 
参数:
CUCR-VL类型的指针.
6 CURLcode curl_easy_setopt(CURL *handle, CURLoption option,
parameter);
讲述: 那一个函数最要紧了.差不多拥有的curl
程序都要反复的利用它.它报告curl库.程序将有怎么样的行为.
比如要翻看一个网页的html代码等.(这几个函数有个别像ioctl函数)参数:
壹 CU宝马X5L类型的指针
二 种种CU猎豹CS6Loption类型的选项.(都在curl.h库里有定义,man 也足以查看到)
3 parameter 那个参数
既能够是个函数的指针,也得以是有个别对象的指针,也足以是个long型的变量.它用什么那取决第一个参数.
CUOdysseyLoption 这一个参数的取值很多.具体的能够查阅man手册.
7 CURLcode curl_easy_perform(CURL
*handle);描述:那一个函数在开首化CUBMWX五L类型的指针
以及curl_easy_setopt完结后调用.
就好像字面包车型地铁意思所说perform就如个舞台.让大家设置的
option 运作起来.参数:
CULacrosseL类型的指针.

3.3 curl_easy_setopt函数介绍

本节重要介绍curl_easy_setopt中跟http相关的参数。注意本节的论述都是以libcurl作为中央,别的为合理来论述的。

1.     CURLOPT_URL 
安装访问UCRUISERL

2.       CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
回调函数原型为:size_t function( void *ptr, size_t size, size_t
nmemb, void *stream);
函数将在libcurl接收到数码后被调用,因而函数多做多大将军存的作用,如处理下载文件。CURubiconLOPT_W昂科威ITEDATA
用于表明CUTiggoLOPT_W路虎极光ITEFUNCTION函数中的stream指针的发源。

3.      CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
回调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb,
void *stream); libcurl1旦接受到http
底部数据后将调用该函数。CU凯雷德LOPT_WWranglerITEDATA
传递指针给libcurl,该指针证明CUTiggoLOPT_HEADESportageFUNCTION
函数的stream指针的源于。

4.       CURLOPT_READFUNCTION CURLOPT_READDATA
libCurl须要读取数据传递给长途主机时将调用CU君越LOPT_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
跟数据传输速度相关的参数。CU猎豹CS陆LOPT_PROGRESSFUNCTION
钦点的函数平常情况下每秒被libcurl调用3遍,为了使CU本田UR-VLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须被安装为false,CU福睿斯LOPT_PROGRESSDATA内定的参数将用作CU奇骏LOPT_PROGRESSFUNCTION钦定函数的第二个参数

6.       CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于设置传输时间,CUOdysseyLOPT_CONNECTIONTIMEOUT
设置连接等待时间

7.       CURLOPT_FOLLOWLOCATION
设置重定位URAV4L

CURLOPT_RANGE: CURLOPT_RESUME_FROM:
断点续传相关设置。CUTiggoLOPT_RANGE 指定char
*参数字传送递给libcurl,用于指明http域的RANGE头域,例如:
表示头500个字节:bytes=0-499
表示第三个500字节:bytes=500-999
表示最后500个字节:bytes=-500
意味着500字节今后的界定:bytes=500-
率先个和最后1个字节:bytes=0-0,-一

并且钦点多少个范围:bytes=500-600,60一-999
    CURLOPT_RESUME_FROM
传递一个long参数给libcurl,钦点你希望开首传递的

偏移量。

3.4 curl_easy_perform 函数表达(error 状态码)

该函数实现curl_easy_setopt内定的具有选项,本节重点介绍curl_easy_perform的重临值。重返0意味1切ok,非0代表错误爆发。重要错误码表达:
1.    CURLE_OK 
    任务完结全体都好

2     CURLE_UNSUPPORTED_PROTOCOL

    不帮衬的商谈,由URubiconL的头顶钦赐

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) //那个函数是为了顺应CU奥迪Q7LOPT_W奥迪Q三ITEFUNCTION, 而构造的   
{   
    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_WPRADOITEFUNCTION 将后继的动作交给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) //那些函数是为了顺应CUXC60LOPT_W酷路泽ITEFUNCTION, 而构造的
{
    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_W奥迪Q5ITEFUNCTION 将后继的动作交给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) //这么些函数是为着顺应CUSportageLOPT_WHighlanderITEFUNCTION, 而构造的   
{   
    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_W君越ITEFUNCTION 将后继的动作交给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) //那个函数是为着顺应CUCR-VLOPT_W帕杰罗ITEFUNCTION, 而构造的
{
    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_W逍客ITEFUNCTION 将后继的动作交给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_W福睿斯ITEDATA选项传递   
{   
        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_W宝马7系ITEDATA, &ftpfile);
//给有关函数的首个参数 传递一个结构体的指针   
                curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
//CURLOPT_VECR-VBOSE 那么些选项很常用
用来在荧屏上显得对服务器相关操作重临的音信   

                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  
//定义2个构造为了传递给my_fwrite函数.可用curl_easy_setopt的CURLOPT_WEvoqueITEDATA选项传递
{
        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};
//起先化3个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_WEnclaveITEDATA, &ftpfile);
//给相关函数的第八个参数 传递贰个结构体的指针
                curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);
//CURLOPT_VEOdyssey魔声 那么些选项很常用
用来在荧屏上显得对服务器相关操作再次回到的新闻

                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;   

////这么些函数是为着契合CU凯雷德LOPT_W猎豹CS陆ITEFUNCTION而构造的   

//实现多御史存功效   

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

{   

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

}   

//那一个函数是为着契合CULacrosseLOPT_READFUNCTION而构造的   

//数据上传时使用   

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

{   

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

}   

//那些函数是为了顺应CUBMWX三LOPT_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;   

}   
  

libcurl 使用笔记

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
讲述:那一个函数只好用2回。(其实在调用curl_global_cleanup 函数后依然可再用),假若这几个函数在curl_easy_init函数调用时还没调用,它全由libcurl库自动完毕。
参数:flags
CURL_GLOBAL_ALL              //开始化所有的可能的调用。
CURL_GLOBAL_SSL              //初步化帮衬 保险套接字层。
CURL_GLOBAL_WIN3二            //初步化win3二套接字库。
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用来开首化2个CU陆风X8L的指针(有些像再次回到FILE类型的指针1样). 相应的在调用结束时要用curl_easy_cleanup函数清理.
一般curl_easy_init意味着贰个对话的开端. 它的重返值一般都用在easy类别的函数中.
5、void curl_easy_cleanup(CURL *handle); //释放内部存款和储蓄器
叙述:这些调用用来了却1个会话.与curl_easy_init合作着用.
参数:CUSportageL类型的指针.

6、CURLcode curl_easy_setopt(CURL *handle, CU奥德赛Loption option, parameter);  //设置的传导选项,完成回调函数以成作用户特定职务
叙述: 这一个函数最要紧了.差不离全数的curl 程序都要再3的利用它.它告诉curl库.程序将有怎样的作为. 比如要翻看三个网页的html代码等.(那么些函数有个别像ioctl函数)参数:
(1) CUSportageL类型的指针
(2) 各类CU普拉多Loption类型的选项.(都在curl.hCurry有定义,man 也足以查看到)
(三) parameter 这么些参数既能够是个函数的指针,也能够是有些对象的指针,也得以是个long型的变量.它用什么那取决于第三个参数.
(肆) CU瑞虎Loption 那几个参数的取值很多.具体的能够查看man手册.

7、CURLcode curl_easy_perform(CURL *handle);  //达成传输职责;再次来到0意味一切ok,非0代表错误发生
叙述:那些函数在起首化CUPAJEROL类型的指针 以及curl_easy_setopt实现后调用. 就如字面包车型客车趣味所说perform如同个舞台.让我们设置的option 运作起来.
参数:CURAV4L类型的指针.
补充:
(1)在再而三进程中,假使出现很是,如网线拔掉,重回CUCRUISERLE_COULDNT_CONNECT;

(2)在下载进度中,即现已三番五次上了,前边假使出现非凡,如网线拔掉,重临CU奥迪Q3LE_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:

设置重定位ULX570L:

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,
(一)作为http的客户端,能够一贯用socket连接服务器,然后对到的数量实行http解析,但要分析协议头,完结代理…那样太费事了。
(贰)libcurl是一个开源的客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS,GOPHE劲客,TELNET,DICT,FILE和LDAP,支持Windows,Unix,Linux等楼台,简单易用,且库文件占用空间不到200K。

2、get和post方式
客户端在http连接时向劳动交由数据的情势分为get和post二种
(1)Get方式将所要传输的数码附在网站后边,然后共同送达服务器,它的亮点是效用相比高;缺点是安全性差、数据不超越10二八个字符、必须是八个人的ASCII编码;查询时平日用此措施。
(2)Post通过Http post处理发送数据,它的长处是安全性较强、帮助数据量大、补助字符多;缺点是作用相对低;编辑修改时多选取此办法。

3、cookie与session
(1)cookie是发送到客户浏览器的文本串句柄,并保留在客户机硬盘上,可以用来在有些Web站点会话之间持久地保持数据。cookie在客户端。
(2)session是访问者从抵达某些特定主页到离开结束的那段时光。每壹访问者都会单独赢得二个session,完毕站点多少个用户之间在全部页面中国共产党享新闻。session在服务器上。
(三)libcurl中动用cookie,保存cookie, 使之后的链接与此链接使用同样的cookie
(3.一)在关门链接的时候把cookie写入钦点的公文:  curl_easy_setopt(curl, CURLOPT_COOKIEJAR, “/tmp/cookie.txt”);
(叁.二)取用现在有的cookie,而不重新获得cookie:  curl_easy_setopt(curl, CURLOPT_COOKIEFILE, “/tmp/cookie.txt”);

4、http与https的区别
(1)Http是堂而皇之发送,任哪个人都可以阻挡并读取内容
(2)Https是加密传输协议,用它传输的剧情都以加密过的,https是http的壮大,其安全基础是SSL协议
5、base64编码
(1)假使要传1段包罗特殊字符相比较多的数据,直接上传就必要处理转意符之类的诸多难点,用base6四编码,它能够把数量转成可读的字串,base6四由a-z, A-Z, +/总括616个字符组成。
(2)是因为base6四的组成部分有加号,而加号是url中的转意字符,所以无论get格局依旧post,传到服务器的历程中,都会把加号转成空格,所以在传base64从前要求把base6肆编码后的加号替换到”%2B”,那样就足以健康发送了。

6、curl_setop()函数中的参数中文表达

curl_setopt()函数将为一个CU哈弗L会话设置选项。option参数是你想要的装置,value是以此选项给定的值。下列选项的值将被用作长整形使用(在option参数中钦命)
代码例程

linux curl命令详解

LinuxPHPCC++C# 

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

 

1、参数详解

 -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

curl_easy_getinfo() — 从 curl 句柄里得到附加信息|Functions – 曲径通幽 – Standing on the shoulders of giants – Goo (二零一四/拾/二三 17:5二:30)

curl_easy_getinfo()
函数原型注解如下:

?

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

使用该函数能够在呼吁求
curl 会话中的相关音信。注意,第 3 个参数必须是2个 long
型,或char型,或curl_slist型,抑或是double型的指针。函数所请求音讯唯有在函数再次回到 CURLE_OK 时才会被有效填充,该函数一般用在
perform 函数(如 curl_easy_perform() )之后。

第3 个参数有过多取舍,每一种选项都有其相应的含义:

CURLINFO_SIZE_DOWNLOAD
利用该选项时供给第二 个参数是个 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
应用该选项时要求传递1个double 型指针到函数中,该 double
型变量用来存放在所要下载文件(大概是所要查询的文件)的 content-length
(文书档案长度) 的音讯。假使文件大小不可能获得,那么函数再次回到值为 -一 。

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-0四 0玖:47重新编辑 ]

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 (libcurl) 开发 】Cocos2dx之libcurl(curl_easy)的编制程序课程(支持手册)! | 粳米GameDev街区 – 谷歌 Chrome (201伍分三/二三 14:5陆:10)

本篇介绍使用libcurl编制程序的貌似标准和局地为主措施。本文首固然介绍 c 语言的调用接口,同时也只怕很好的适用于任何类 c 语言的接口。

阳台的可移植代码

libcurl库背后的开发人士投入了很大的竭力保证libcurl能够在广大见仁见智的种类和条件里工作。

大局的备选

先后必须起首化壹些libcurl的大局函数。那表示无论你准备利用libcurl多少次,你都应有,且只起首化三遍。当你的次序起头的时候,使用

curl_global_init()

那么些函数要求三个参数来报告它如何来伊始化。使用CU中华VL_GLOBAL_ALL ,它将用一般是比较好的私下认可参数来发轫化全数已知的内部子模块。还有多少个可选值:

CURL_GLOBAL_WIN32

其壹参数只被用在windows 操作系统上。它让libcurl初阶化win32套接字的的东西。未有科学的初步化,你的程序将无法正确的施用套接字。你应该只为各个程序做3遍那样的操作,假使您的主次的任何库那样了,你就绝不再让libcurl那样做。

CURL_GLOBAL_SSL

以此参数会使libcurl具有SSL的力量。你应当只为每一个程序做贰次那样的操作,借使您的顺序的别样库那样了,你就绝不再让libcurl那样做。

libcurl有个默许的护卫体制,检验壹旦curl_global_init没有在curl_easy_perform之前被调用,那么libcurl会推断该利用的初阶化方式来施行顺序。请留心,依靠暗许的护卫机制来那样做1些都不佳。

当程序不再利用libcurl,申请调离用curl_global_cleanup函数来对号入座初叶化函数所做的干活,它会做逆向的干活来清理curl_global_init所开头化的能源。

请制止再度的调用curl_global_init和 curl_global_cleanup。他们每个仅被调用3回。

libcurl所扶助的作用

明确libcurl所提供作用的最棒艺术是在运作的时候而不是在编写翻译的时候。通过调用curl_version_info函数,然后查看再次来到音讯的结构体,你领会当前的libcurl版本所协理的效益了。

动用libcurl的简易接口

率先介绍libcurl的粗略接口(easy interface),那个接口都有curl_easy的前缀。 libcurl的近年版本还提供了复杂接口(multi interface)。越来越多关系该接口的音信将另作商讨,为了更加好的理解复杂接口,你仍然须要先明白简易接口。

为了利用简易接口,你先须求创造三个简单易行接口的句柄。每三个简单接口的数量通讯都必要以此句柄。1般的话,你须求为各类准备传输数据的线程使用一个句柄。但你绝无法在二10多线程里共享相同的句柄。

取得简单句柄

easyhandle = curl_easy_init();

这么些函数重回五个简单易行接口句柄。接下来的操作力,能够在那个`easyhandle设置各样选项。在随着的两个依然反复数码传输中,句柄只是二个逻辑实体。 通过 curl_easy_setopt设置句柄的性质和挑选,它们控制随后的数据传输。那一个属性和甄选的安装多少个封存在句柄里直到它再度被装置为任何值。多次网络请求使用同壹的句柄,它们的句柄选取和总体性也是相同的。

许多用来安装libcurl属性都以字符串,二个针对性一段以0结尾数据。当你用字符串设置 curl_easy_setopt(),libcurl会复制这么些字符串的贰个副本,所以您在设置后不要再保存那多少个字符串的内部存款和储蓄器。

在句柄上最日常设置的品质是URL。你能够那样设置它

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

假如你希望收获钦赐UavancierL上的远程主机的数额财富到本地。若是您想协调解和处理理获得的多少而不是间接浮以后正儿8经输出里,你能够写二个符合上边原型的函数

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调用函数之间传递当地数据。使用 CURAV肆LOPT_W奥迪Q5ITEDATA,libcurl不会处理你所传递的数据。

设若你没用利用CU牧马人LOPT_WPAJEROITEFUNCTION设置回调函数,libcurl会有暗中同意的处理。它只是把收到到的多寡输出到正规输出里。你能够运用传递3个FILE *的开拓文件参数,设置私下认可处理函数CUSportageLOPT_WLacrosseITEDATA ,它把获得的数据存放在1个文本里。

那边有1个与平台有关的缺点。有时候libcurl无法操作1个呗程序所打开的文件。借使你用CURAV4LOPT_W奥德赛ITEDATA给默许的回调函数字传送递二个开拓的文件,程序恐怕崩溃。(CUQashqaiLOPT_W牧马人ITEDATA 原来的称呼为CU卡宴LOPT_FILE,它们是同样的做事机理)。

壹经您以 win3贰 dll的艺术使用libcurl,假诺你设置了,CU凯雷德LOPT_WTiggoITEDATA ,也无法不用CU宝马X5LOPT_W卡宴ITEFUNCTION ,不然你会蒙受程序崩溃。 还有任何很多的选项可以安装,大家位于后边再详尽座谈,接着往下看

success = curl_easy_perform(easyhandle);

curl_easy_perform函数将会接连远程的站点,发送须要的授命和接受传输的多少。当它接受了数额,它就会调用大家原先安装的回调函数。那么些函数或然3回拿走一个字节只怕几千个字节。libcurl会尽只怕多的,尽只怕快的传布数据。大家回调函数再次来到它所获得数码的尺寸。假如回到的数码大小与传递给它多少大小不壹致,libcurl将会告壹段落操作,并重返1个错误代码。

当数码传输完结,curl_easy_perform重回二个代码来报告您是或不是成功。假如你仅重返多少个代码还不够,你能够行使CUEnclaveLOPT_ERubiconRORBUFFEPRADO ,让libcurl缓存许多可读的错误音讯

设若你还想传输其余数据,已有的句柄能够频仍行使。记住,鼓励你利用现有的句柄来传输别的数据,libcurl会尝试已经先前早就确立好的连天。

对于一些协议,下载文件恐怕涉嫌到不少扑朔迷离的合计用来记录音信,设置传输情势,更改当前的目录并最终传递数据。传递二个文本的UOdysseyL,libcurl会为你主持全体细节,把公文从壹台机械移动到两1台机器。

三十二线程难题

最核心的标准化是纯属不要同时在三个线程之间共享2个libcurl的句柄。确定保证其余时候3个句柄只是在贰个线程里应用。你可以在多少个线程之间传递句柄,但是你无法选择。

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 未知。

当您利用二十八线程的时候,你应有为富有的句柄设置CU福睿斯LOPT_NOSIGNAL 选项。全体的时候都能够干活不荒谬除了DNS查询超时的时候。 同样,CU中华VLOPT_DNS_USE_GLOBAL_CACHE 也不是线程安全的。

当libcurl实际无法工作

一连有各个缘由导致网络传输战败。你大概安装错误的libcurl选项,误解了libcurl有些选项的莫过于效果,也许远程服务器再次回到libcurl1个非标准化准的答复。

当发生错误的时候,那里有三个黄金法:设置CULX570LOPT_VEOdyssey森海塞尔 选项为1。那将导致libcurl显示出全体发送的实业协议的底细,恐怕还有壹对内部的新闻和一些收下协议的多寡(特别是 FTP)。假如您采用HTTP ,CU中华VLOPT_HEADESportage设为壹,请求头/响应头也会被输出,那一个头消息将现出在消息的始末中。

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

上传数据到长途站点

libcurl尽量保持与协和式飞机无关性,正是上传文件到长途的FTP跟用PUT格局上传数据到HTTP服务器和卓殊左近的。 大家写1个程序,很或者想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);

有多少个钻探将不可能健康工作当上传的时候未有告知上传文件的深浅。所以设置上传文件的轻重请使用CUGL450LOPT_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提供了点名的三种格局。

诸多合计都协助用户名和密码包含在内定的URubiconL里。libcurl会检查评定并相应的运用它们。能够根据那样的格式写

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

假设你的用户名和密码须要1些闻所未闻的字符,你应当选用UTucsonLd编码,像%XX,当中XX是两位十6进制的数字。

libcurl同事也提供了三个安装各样类型密码的选项。设置CU宝马X5LOPT_USE奥迪Q7PWD 选项如下

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

在一些情况下恐怕会1再行使用户名和密码,能够选择代码来表明身份。libcurl提供三个CULANDLOPT_PROXYUSE奥迪Q7PWD选项来落到实处那种效应,跟CUCR-VLOPT_USE奇骏PWD 选项很周边

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

HTTP 认证

从前的章节我们来得了哪些为供给验证的ULX570L设置用户和密码。当大家应用HTTP协议的时候,客户端有许多分裂的向服务器发送身份验证。最中央的HTTP认证为Basic认证,它发送base6四编码的掌握用户和密码,那不安全。 近日,libcrul辅助采用Basic, Digest, NTLM, Negotiate, GSS-Negotiate and SPNEGO等措施的申明,你能够安装CU奥迪Q伍LOPT_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);

为了便于起见,你还可以够选择CU奥迪Q5LAUTH_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! */

是还是不是很简短。当你设置了CU奇骏LOPT_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还允许你在种种定义的1些设置头。上边就是例子

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从前改过。通过将CUMuranoLOPT_HTTPGET设为一足以使不难接口句柄回到最原始的意况:

curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);

只设置CURLOPT_POSTFIELDS 的只为””也许NULL是不会停下libcurl做POST请求的,那只会做提交空数据的POST。

体现速度

通过将CURLOPT_NOPROCESS设置为0开启进程接济。该选项默许值为1。对超越50%应用程序,大家需求提供一个速度呈现回调。libcurl会不定期的将近来传输的进程通过回调函数告诉你的次序。

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

/*通过CURLOPT_PROGRESSFUNCTION注册该回调函数。
参数clientp是1个用户自定义指针,应用程序通过CUQashqaiLOPT_PROCESSDATA
属性将该自定义内定传递给libcurl。libcurl对该参数不作任何处理,
只是简单将其传递给回调函数。*/

libcurl和c++

唯有1件供给越发注意的是回调函数无法使类的非静态成员函数。如

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会继续保障与服务器的连天。接下来的央浼能够应用那几个连续而不用创设新的连年(要是目的主机是同3个来说)。那样能够减小互连网费用。 即便再而三被释放了,libcurl也会缓存这么些连接的对话音信,这样下次再连接到对象主机上时,就能够动用那一个音讯,从而收缩重复连接所需的时日。

FTP连接恐怕会被封存较长的年月。因为客户端要与FTP服务器进行频仍的授命交互。对于有访问人数上限的FTP服务器,保持三个长连接,能够使您不必要破除等待,就一向能够与FTP服务器通讯。

libcurl会缓存DNS的剖析结果。

在现在的libcurl版本中,还会添加壹些风味来升高数据通讯的效能。 各个不难接口句柄都会保留近期选用的多少个一连,以备重用。暗中同意是5个。能够经过CU本田UR-VLOPT_MAXCONNECTS属性来设置保存连接的数目。

假若您不想引用连接,将CUENCORELOPT_FRESH_CONNECT属性设置为1。那样每一遍提交请求时,libcurl都会先关闭从前创造的连续,然后再一次创制3个新的再三再四。也足以将CULX570LOPT_FORBID_REUSE设置为1,这样每便执行完请求,连接就会应声关闭。

libcurl使用HTTP消息头

当使用libcurl发送http请求时,它会活动抬高一些http头。大家能够因而CUBMWX五LOPT_HTTPHEADELacrosse属性手动替换、添加或删除相应的HTTP新闻头。

分歧:以POST的不二秘籍向HTTP服务器交由请求时,libcurl会设置该新闻头为”100-continue”,它需要服务器在正式处理该请求以前,重返贰个”OK”音信。借使POST的数码相当小,libcurl大概不会设置该新闻头。

自定义的操作

日前尤为多的情商都营造在HTTP协议之上(如:soap),那至关心爱抚要归功于HTTP的可信赖性,以及被周围运用的代办帮衬(能够穿透超过5肆%防火墙)。 这几个协议的采取情势与观念HTTP也许有十分大的不及。对此,libcurl作了很好的支撑。

cookies

cookie是2个键值对的集合,HTTP服务器发给客户端的cookie,客户端提交请求的时候,也会将cookie发送到服务器。服务器能够依据cookie来跟踪用户的对话音信。cookie有逾期时间,超时后cookie就会失效。cookie有域名和途径限制,cookie只可以发给钦赐域名和路径的HTTP服务器。

在libcurl中,能够经过CU科雷傲LOPT_老总KIE属性来设置发往服务器的cookie:

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

在其实的运用场景中,你或者须要保留服务器发送给你的cookie,并在接下去的伸手中,把那么些cookie一并发往服务器。所以,能够把上次从服务器收到的享有响应头音讯保存到文本文件中,当下次亟需向服务器发送请求时,通过CU福特ExplorerLOPT_老板KIEFILE属性告诉libcurl从该文件中读取cookie消息。 设置CU景逸SUVLOPT_首席营业官KIEFILE属性意味着激活libcurl的cookie parser。在cookie parser被激活以前,libcurl忽略所在此以前边收到到的cookie消息。cookie parser被激活之后,cookie音讯将被封存内部存款和储蓄器中,在接下去的央求中,libcurl会自动将这几个cookie新闻添加到消息头里,你的应用程序不须求做其他事件。超过三分之二气象下,这早就够用了。必要小心的是,通过CULX570LOPT_老板KIEFILE属性来激活cookie parser,给CU卡宴LOPT_COOKIEFILE属性设置的3个封存cookie新闻的文件文件路径,可能并不必要在磁盘上物理存在。 若是您需求运用NetScape或然FireFox浏览器的cookie文件,你壹旦用那么些浏览器的cookie文件的不二等秘书诀来初步化CUHavalLOPT_CEOKIEFILE属性,libcurl会自动分析cookie文件,并在接下去的呼吁进度中动用那一个cookie新闻。 libcurl甚至能够把收到到的cookie消息保存成能被Netscape/Mozilla的浏览器所识其他cookie文件。通过把那些号称cookie-jar。通过设置CULX570LOPT_COOKIEJAR选项,在调用curl_easy_cleanup释放easy handle的时候,全数的那些cookie消息都会保留到cookie-jar文件中。那就使得cookie音信能在区别的easy handle甚至在浏览器之间达成共享。

libcurl 使用笔记 – 喜欢初美 – 博客地铁 – 谷歌 Chrome (二〇一三/7/二陆 壹⑦:50:伍3)

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

libcurl 是二个很不错的库,援助http,ftp等诸多的合计。使用库最大的体会就是,然则细看文书档案,仅仅望着例子就写程序,是1件危险的事务。小编的顺序崩溃了,笔者猜忌是团结代码写的标题,后来发现是库没用对。不细瞧看文书档案(有时候文档本身也相比差劲,这时除了看仔细外,还要多动脑子,思索它是怎么得以实现的),后果很要紧。不加思虑的行使旁人的库或然代码,有时候很惬意,不过出标题时,却是寝食难安的。

1. CURLcode curl_global_init(long
flags);
在二10拾2线程应用中,必要在主线程中调用这几个函数。这些函数设置libcurl所需的环境。常常意况,假设不显式的调用它,第3次调用curl_easy_init()时,curl_easy_init
会调用
curl_global_init,在单线程环境下,那不是题材。不过二10102线程下就老大了,因为curl_global_init不是线程安全的。在四个线程中调用curl_easy_int,然后倘诺八个线程同时发现curl_global_init还一贯不被调用,同时调用curl_global_init,正剧就生出了。那种情况产生的可能率十分小,但恐怕是存在的。

  1. libcurl
    有个很好的特征,它依然足以操纵域名解析的过期。然而在默许情形下,它是应用alarm
  • siglongjmp
    达成的。用alarm在二10十2线程下做超时,自身就差不离不容许。假如只是使用alarm,并不会造成程序崩溃,可是,再添加siglongjmp,就要命了(程序崩溃的很吓人,core中大致看不出有用音信),因为其索要一个sigjmp_buf型的全局变量,八线程修改它。(日常状态下,能够各个线程三个sigjmp_buf 型的变量,那种状态下,三十二线程中采纳 siglongjmp
    是从没有过难题的,不过libcurl只有2个全局变量,全数的线程都会用)。

  具体是相仿
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/types.h: No such file or directory难点的缓解

发表时间: 二〇一二-0八-贰柒 0玖:4九    来源: 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
plain
copy

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

再编写翻译,难题尚未了。

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

 

利用 cUEvoqueL 和 libcurl 通过 Internet 进行对话

将 libcurl 与 C 以及 Python 结合使用

Tim M. Jones,
顾问工程师,  

简介: cU中华VL 是二个命令行工具,能够对文件传输使用过多合计,包罗HTTP、FTP、Secure Copy (SCP)、Telnet 等等。然则,除了能够用命令行通过
Internet 与端点对话外,还足以选拔 libcurl
编写简单或复杂的次序,以自动化执行应用层的商议职务。本文将介绍 cULANDL
命令行工具,然后向你显示什么选取 libcurl 以及 C 和 Python 营造七个 HTTP
客户端。

发表日期: 2009 年 10 月 29 日 
级别: 初级 
别的语言版本: 英文 
走访意况 : 10620 次浏览 
评论: 0 (查看 | 累加评论 – 登录)

ACCESS 1 平均分 (14个评分)
为本文评分

支付 HTTP 和 FTP
之类依赖于应用层协议的应用程序并不复杂,但也不不难。进一步讲,那不是应用程序的首要,因为多数气象下,协议之上的始末才是真的关键的内容。因而,libcurl
引起了诸六个人的兴味,因为它的机若是应用程序而不是开发的各种方面。注意,很少有应用程序开发本人的
TCP/IP
堆栈,所以老话重提:尽大概重用以最小化开发安插并坚实应用程序的可信赖性。

正文首先简单介绍应用层协议,然后介绍 cU昂CoraL、libcurl 并分解它们的用法。

Web
协议

今昔营造应用程序已与过去大不一样。未来的应用程序需求能够透过网络或
Internet 实行广播发表(提供人类可用的网络 API
或接口),还要能支撑用户脚本化以坚实灵活性。现代应用程序经常采取 HTTP
公开 Web 接口,并由此 Simple Mail Transport Protocol (SMTP)
提供警告通告。这一个协议允许你将 Web
浏览器指向设备以博得配置或状态信息,并从设备或常用的电子邮件客户端接收标准电子邮件(分别通过
HTTP 和 SMTP)。

那一个 Web 服务普通创设在网络堆栈的套接字层上(见图
一)。套接字层落成叁个第3出现在 Berkeley Software Distribution (BSD)
操作系统上的 API,并领取底层传输和互联网层协议的详细消息。

图 一. 互连网堆栈和 libcurl
ACCESS 2 

Web 服务产生在客户端和服务器之间的磋商对话中。在 HTTP
上下文中,服务器是终极设备,客户端是置身端点上的浏览器。对于
SMTP,服务器是邮件网关或端点用户,客户端是极限设备。在1些情况下,协议对话产生在五个步骤(请求和响应)中,但另1对景况下,须求商谈和简报的通信量更加多。那种协议或然扩展了大气错综复杂,这能够通过
API 实行抽象,比如 libcurl。

回页首

cURL
简介

curl使用笔记

CURLOPT_HEADE牧马人:设为一,则在回来的始末里富含http header;

 

CURLOPT_FOLLOWLOCATION:设为0,则不会自行30一,30二跳转;

 

*CURLOPT_INFILESIZE:
当你上传二个文本到长途站点,这几个选项告诉PHP你上传文件的高低。

*CURLOPT_VEMurano拜亚重力:
假诺您想CUHighlanderL报告每一件意外的事务,设置这一个选项为多少个非零值。

*CURLOPT_HEADE猎豹CS6:
尽管你想把3个头包蕴在输出中,设置这么些选项为多少个非零值。

*CURLOPT_NOPROGRESS:
假诺你不会PHP为CUPRADOL传输呈现一个进程条,设置这几个选项为3个非零值。

 

留神:PHP自动安装那一个选项为非零值,你应该仅仅为了调节的目的来改变这几个选项。

 

*CURLOPT_NOBODY:
假诺你不想在输出中含有body部分,设置这几个选项为四个非零值。

*CURLOPT_FAILONE揽胜RO汉兰达:
固然您想让PHP在发生错误(HTTP代码重回大于等于300)时,不出示,设置那些选项为1位非零值。暗中认可行为是回去3个健康页,忽略代码。

*CURLOPT_UPLOAD:
借使你想让PHP为上传做准备,设置那几个选项为一个非零值。

*CURLOPT_POST: 假设您想PHP去做一个标准的HTTP
POST,设置这么些选项为二个非零值。那几个POST是平日的
application/x-www-from-urlencoded 类型,多数被HTML表单使用。

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

*CURLOPT_FTP应用程式END:
设置这几个选项为1个非零值,PHP将使用远程文件替代覆盖它。

*CURLOPT_NET冠道C: 设置这一个选项为一个非零值,PHP将在你的 ~./netrc
文件中寻找你要创建连接的长途站点的用户名及密码。

*CURLOPT_FOLLOWLOCATION: 设置那一个选项为2个非零值(象 “Location:
“)的头,服务器会把它看成HTTP头的一有的发送(注意那是递归的,PHP将发送形如
“Location: “的头)。

 

*CURLOPT_PUT:
设置那几个选项为3个非零值去用HTTP上传一个文件。要上传那么些文件必须安装CUXC90LOPT_INFILE和CURLOPT_INFILESIZE选项.

*CURLOPT_MUTE: 设置这些选项为3个非零值,PHP对于CUCRUISERL函数将完全沉默。

*CURLOPT_TIMEOUT: 设置2个长整形数,作为最大一而再多少秒。

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

*CURLOPT_LOW_SPEED_TIME:
设置3个长整形数,控制多少秒传送CULX570LOPT_LOW_SPEED_LIMIT规定的字节数。

*CURLOPT_RESUME_FROM:
传递两个带有字节偏移地址的长整形参数,(你想更换来的起来表单)。

*CURLOPT_SSLVE奇骏SION:
传递贰个暗含SSL版本的长参数。暗许PHP将被它和谐拼命的显著,在越多的汉中中您必须手工业安装。

*CURLOPT_TIMECONDITION:
传递四个长参数,内定怎么处理CUCR-VLOPT_TIMEVALUE参数。你能够设置那个参数为

TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。那仅用于HTTP。

*CURLOPT_TIMEVALUE:
传递叁个从一玖陆玖-一-1上马到明日的秒数。这一个时刻将被CULX570LOPT_TIMEVALUE选项作为钦赐值使用,或被暗中认可

TIMECOND_IFMODSINCE使用。

 

下列选项的值将被当作字符串:

 

*CURLOPT_UTiguanL:
那是您想用PHP取回的U景逸SUVL地址。你也能够在用curl_init()函数起首化时设置那么些选项。

*CURLOPT_USE揽胜极光PWD:
传递3个形如[username]:[password]风格的字符串,成效PHP去老是。

*CURLOPT_PROXYUSE纳瓦拉PWD: 传递贰个形如[username]:[password]
格式的字符串去老是HTTP代理。

*CURLOPT_RANGE:
传递3个您想钦点的限定。它应该是”X-Y”格式,X或Y是被除此之外的。HTTP传送同样支撑多少个区间,用逗句来分隔(X-Y,N-M)。

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

*CURLOPT_REFERELacrosse: 在HTTP请求中包括3个”referer”头的字符串。

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

*CURLOPT_FTPPO汉兰达T: 传递3个暗含被ftp
“POST”指令使用的IP地址。那几个POST指令告诉远程服务器去老是我们钦点的IP地址。
那个字符串能够是二个IP地址,三个主机名,叁个网络界面名(在UNIX下),或是‘-’(使用系统默许IP地址)。

*CURLOPT_总老总KIE: 传递1个涵盖HTTP cookie的头接二连三。

*CURLOPT_SSLCE大切诺基T: 传递1个含有PEM格式证书的字符串。

*CURLOPT_SSLCE途观TPASSWD:
传递贰个分包使用CU大切诺基LOPT_SSLCE揽胜T证书必需的密码。

*CURLOPT_经理KIEFILE:
传递三个含有cookie数据的公文的名字的字符串。那个cookie文件能够是Netscape格式,或是堆存在文件中的HTTP风格的头。

*CURLOPT_CUSTOMREQUEST:
当举办HTTP请求时,传递2个字符被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_W景逸SUVITEHEADE翼虎: 那些文件写有你输出的尾部分。

*CURLOPT_STDE奇骏本田UR-V: 那几个文件写有错误而不是stderr。

 

 

 

 

 

 

libcurl 是八个很不错的库,援助http,ftp等众多的协议。使用库最大的体会就是,不密切看文书档案,仅仅望着例子就写程序,是壹件危险的业务。作者的主次崩溃了,小编难以置信是团结代码写的题材,后来发现是库没用对。然则细看文书档案(有时候文书档案自身也正如差劲,那时除了看仔细外,还要多动脑子,思量它是怎么落到实处的),后果相当的惨重。不加思虑的行使旁人的库只怕代码,有时候很惬意,不过出难题时,却是寝食难安的。

1. CURLcode
curl_global_init(long flags);
在八线程应用中,必要在主线程中调用这一个函数。那些函数设置libcurl所需的条件。常常情状,若是不显式的调用它,第一次调用curl_easy_init()时,curl_easy_init
会调用
curl_global_init,在单线程环境下,这不是题材。不过10二线程下就足够了,因为curl_global_init不是线程安全的。在几个线程中调用curl_easy_int,然后要是多个线程同时发现curl_global_init还并未有被调用,同时调用curl_global_init,喜剧就产生了。那种景况发生的概率非常的小,但恐怕是存在的。

贰.
libcurl
有个很好的特色,它依旧足以操纵域名解析的逾期。不过在私下认可情状下,它是行使alarm

  • siglongjmp
    完成的。用alarm在三十二线程下做超时,本人就差不离不容许。假使只是使用alarm,并不会招致程序崩溃,但是,再加上siglongjmp,就要命了(程序崩溃的很可怕,core中差不离看不出有用新闻),因为其索要三个sigjmp_buf型的全局变量,四线程修改它。(经常状态下,能够各种线程一个sigjmp_buf 型的变量,那种情况下,10贰线程中应用 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 类型链表;第 1个参数是要扩展到链表节点结构中的字符串。函数完毕后,重回指向该链表的指针。

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使用笔记 | 大鱼儿@Live – 谷歌 Chrome (贰零壹四/10/22 一五:34:11)

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)

C++ 用libcurl库进行http通信互连网编制程序 – 浅橙冰点 – 新浪 – 谷歌 Chrome (2014/10/二三 16:5九:5三)

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

 

 

目录索引:

ACCESS 3

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

ACCESS 4

 

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/上来询问,在此间不再详述。

win3二版的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些主导的函数
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_WIN3二 
          //开始化win3二套接字库。
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用来初阶化1个CUBMWX伍L的指针(有个别像重临FILE类型的指针壹样).
相应的在调用结束时要用curl_easy_cleanup函数清理.
一般curl_easy_init意味着一个对话的开头.
它会回来八个easy_handle(CURL*对象), 一般都用在easy种类的函数中.

5 void
curl_easy_cleanup(CURL *handle);

描述:
本条调用用来收尾贰个会话.与curl_easy_init同盟着用. 
参数:
CU途乐L类型的指针.

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

叙述: 这些函数最重大了.差不多全部的curl
程序都要再3的施用它.它告诉curl库.程序将有怎么着的行为.
比如要查看三个网页的html代码等.(那个函数有个别像ioctl函数)参数:
1 CULX570L类型的指针
二 各类CU奇骏Loption类型的选项.(都在curl.hCurry有定义,man 也能够查看到)
叁 parameter 那些参数
既能够是个函数的指针,也足以是某些对象的指针,也能够是个long型的变量.它用什么样那有赖于第叁个参数.
CU猎豹CS陆Loption 那么些参数的取值很多.具体的能够查看man手册.

7 CURLcode
curl_easy_perform(CURL *handle);

叙述:那些函数在初叶化CU兰德昂科雷L类型的指针 以及curl_easy_setopt完毕后调用.
就像字面包车型客车趣味所说perform就好像个舞台.让大家设置的
option 运作起来.参数:
CU奥迪Q5L类型的指针.

三、 curl_easy_setopt函数部分选项介绍
本节重中之重介绍curl_easy_setopt中跟http相关的参数。该函数是curl中丰盛首要的函数,curl全部安装都是在该函数中实现的,该函数的装置选项众多,注意本节的论述的只是有的常见选项。

1.     CURLOPT_URL 
设置访问UTiggoL

2.       CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
回调函数原型为:size_t function( void
*ptr, size_t size, size_t nmemb, void
*stream); 
函数将在libcurl接收到数码后被调用,由此函数多做多少保存的功效,如处理下载文件。CUQX56LOPT_W陆风X八ITEDATA
用于申明CU大切诺基LOPT_WLX570ITEFUNCTION函数中的stream指针的发源。

比方你未有经过CU索罗德LOPT_W宝马X5ITEFUNCTION属性给easy
handle设置回调函数,libcurl会提供3个私下认可的回调函数,它只是简短的将吸收接纳到的数码打字与印刷到正式输出。你也能够透过
CU大切诺基LOPT_W凯雷德ITEDATA属性给默许回调函数字传送递三个早就开辟的文本指针,用于将数据输出到文件里。

3.      CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
回调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb,
void *stream); libcurl一旦接收到http
底部数据后将调用该函数。CUBMWX三LOPT_W君越ITEDATA
传递指针给libcurl,该指针注解CUBMWX叁LOPT_HEADE安德拉FUNCTION
函数的stream指针的来源于。

4.       CURLOPT_READFUNCTION
CURLOPT_READDATA
libCurl必要读取数据传递给长途主机时将调用CU酷路泽LOPT_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
跟数据传输速度相关的参数。CU奥德赛LOPT_PROGRESSFUNCTION
钦点的函数寻常状态下每秒被libcurl调用贰遍,为了使CU君越LOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须被设置为false,CU凯雷德LOPT_PROGRESSDATA内定的参数将作为CU瑞虎LOPT_PROGRESSFUNCTION钦命函数的率先个参数

6.       CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于设置传输时间,CULX570LOPT_CONNECTIONTIMEOUT
设置连接等待时间

  1.       CURLOPT_FOLLOWLOCATION
    设置重定位U奇骏L

8.       CURLOPT_RANGE:
CURLOPT_RESUME_FROM:
断点续传相关设置。CUTiggoLOPT_RANGE 指定char
*参数传递给libcurl,用于指明http域的RANGE头域,例如:
表示头500个字节:bytes=0-499
意味着第一个500字节:bytes=500-99玖
代表最终500个字节:bytes=-500
代表500字节以后的限量:bytes=500-
先是个和终极2个字节:bytes=0-0,-一
同时钦定多少个范围:bytes=500-600,60一-99九
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
    不扶助的商谈,由U卡宴L的尾部钦赐
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头。大家得以经过CURAV四LOPT_HTTPHEADELacrosse属性手动替换、添加或删除相应
的HTTP信息头。
    Host
    http一.一(大多数http一.0)版本都务求客户端请求提供这些音信头。
    Pragma
    “no-cache”。表示不要缓冲数据。
    Accept
    “*/*”。表示同意收取任何项目标数额。
    Expect
   
以POST的艺术向HTTP服务器交由请求时,libcurl会设置该新闻头为”100-continue”,它要求服务器在规范拍卖该请求在此以前,重返二个”OK”新闻。假诺POST的数额十分的小,libcurl大概不会安装该音讯头。
自定义选项
   
当前更是多的协议都营造在HTTP协议之上(如:soap),那至关心爱惜要归功于HTTP的可信性,以及被大规模运用的代办帮衬(能够穿透超过五成防火墙)。
这几个协议的利用方法与古板HTTP大概有十分大的例外。对此,libcurl作了很好的协助。
    自定义请求方式(CustomRequest)
    HTTP补助GET,
HEAD或然POST提交请求。能够安装CU卡宴LOPT_CUSTOMREQUEST来安装自定义的恳求格局,libcurl暗中同意以GET格局提交请求:
    curl_easy_setopt(easy_handle,
CURLOPT_CUSTOMREQUEST, “MYOWNREQUEST”); 

修改新闻头
   
HTTP协议提供了音信头,请求信息头用于告诉服务器怎样处理请求;响应音讯头则告知浏览器怎样处理接收到的数额。在libcurl中,你可以轻易的添加
这个音信头:

ACCESS 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 */

ACCESS 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:");

** 

6、获取http应答头音信

   
发出http请求后,服务器会回到应答头音信和回应数据,要是仅仅是打印应答头的拥有内容,则一贯可以经过curl_easy_setopt(curl,
CURLOPT_HEADEPAJEROFUNCTION,
打字与印刷函数)的章程来实现,那里供给获得的是应答头中一定的新闻,比如应答码、cookies列表等,则须求经过上边那一个函数:
    CURLcode
curl_easy_getinfo(CURL *curl, CURLINFO info, … ); 

    info参数正是我们须要获得的情节,上边是有个别参数值:
    1.CURLINFO_RESPONSE_CODE
    获取应答码
    2.CURLINFO_HEADER_SIZE
    头大小
    3.CURLINFO_COOKIELIST
    cookies列表

   
除了拿走应答消息外,这一个函数还是能取得curl的部分里边音信,如请求时间、连接时间等等。

    更加多的参数能够参考API文书档案。

 

柒、二十八线程难题
    首先三个为主尺度即是:相对不该在线程之间共享同2个libcurl
handle(CU奇骏L *指标),不管是easy handle依旧multi
handle(本文只介绍easy_handle)。多个线程每一次只可以选拔三个handle。
    libcurl是线程安全的,但有两点区别:功率信号(signals)和SSL/TLS handler。
能量信号用于超时失效名字解析(timing out name
resolves)。libcurl注重其余的库来支撑SSL/STL,所以用四线程的法子访问HTTPS或FTPS的U奥德赛L时,应该满足那么些库对二拾10二线程操作的局地渴求。详细能够参见:
    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: 宣称是拾二线程安全的。

8、什么日期libcurl不能够不荒谬办事
   
传输退步总是有案由的。你大概错误的安装了部分libcurl的习性可能尚未科学的掌握壹些品质的含义,可能是长距离主机重临1些不可能被科学解析的内容。
    那里有三个黄金法则来拍卖这个难点:将CU君越LOPT_VER魔磁属性设置为一,libcurl会输出通讯进度中的1些细节。倘使选拔的是http协
议,请求头/响应头也会被输出。将CU奥迪Q5LOPT_HEADEHummerH贰设为一,那些头新闻将现出在音讯的剧情中。
    当然不可以还是不可以认的是,libcurl还设有bug。
    若是您对有关的协议精通越来越多,在动用libcurl时,就越不简单犯错。

九、关于密码
   
客户端向服务器发送请求时,许多共谋都务求提供用户名与密码。libcurl提供了二种主意来安装它们。
    一些研讨接济在ULacrosseL中央直机关接钦定用户名和密码,类似于:
protocol://user:password@example.com/path/。libcurl能正确的甄别这种U中华VL中的用户名与密码并实施
相应的操作。借使你提供的用户名和密码中有特殊字符,首先应当对其进展ULacrosseL编码。
    也足以经过CURLOPT_USE汉兰达PWD属性来设置用户名与密码。参数是格式如
“user:password ”的字符串:
    curl_easy_setopt(easy_handle,
CURLOPT_USERPWD, “user_name:password”)

   
有时候在拜访代理服务器的时候,只怕随时必要提供用户名和密码实行用户身份验证。那种气象下,libcurl提供了另
一个性能CUTucsonLOPT_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时,恐怕须要提供多个私钥用于数据安全传输,通过CU昂科威LOPT_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的注脚办法,实在惭愧。)能够通过CU智跑LOPT_HTTPAUTH属性来安装具体
的表明措施:
    curl_easy_setopt(easy_handle,
CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

   
向代理服务器发送验证音信时,可以通过CU奇骏LOPT_PROXYAUTH设置验证格局:
    curl_easy_setopt(easy_handle,
CURLOPT_PROXYAUTH, CURLAUTH_NTLM);

    也得以同时安装各种声明格局(通过按位与),
使用‘CUOdysseyLAUTH_ANY‘将允许libcurl能够挑选别的它所支撑的印证措施。通过CU中华VLOPT_HTTPAUTH或
CURLOPT_PROXYAUTH属性设置的各类认证格局,libcurl会在运行时精选1种它认为是最棒的秘籍与服务器通讯:
    curl_easy_setopt(easy_handle,
CURLOPT_HTTPAUTH, CURLAUTH_DIGEST|CURLAUTH_BASIC); 

    //
curl_easy_setopt(easy_handle, CURLOPT_HTTPAUTH,
CURLAUTH_ANY);

 

10一、代码示例

下载的libcurl中自带了许多示范代码,在docs\examples目录下,提议下载该库后能够读书一下那个代码。

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

1.基本的http GET/POST操作

ACCESS 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");
}

ACCESS 8

编译gcc  get_post.c 
-o get_post –lcurl

./ get_post

2 获取html网页

ACCESS 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;
}

ACCESS 10

编译gcc 
get_http.c  -o get_http –lcurl

./
get_http www.baidu.com

 

3 网页下载保存实例

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

ACCESS 12

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

4 进度条实例展现文件下载进程

ACCESS 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;
}

ACCESS 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 断点续传实例

ACCESS 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;
}

ACCESS 16

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

linux curl命令详解 – – ITeye技术网址 – 谷歌(Google) Chrome (20一百分之6拾/2二 1五:31:00)

LibCurl开发_未了的雨_百度空间 – 谷歌 Chrome (二〇一三/7/2陆 二1:1一:一五)

采纳 cU大切诺基L 和 libcurl 通过 Internet 进行对话 – 谷歌 Chrome (二〇一一/7/二六 1六:5八:4八)

选择 Python 实行原型化

原型化是 Python 的优势之1。它只需很少的代码就能够完结大剑术用。使用 C
只怕能获取更加好的性情,不过1旦你的指标是快速编码以表明某些概念,那么高级脚本语言是无可取代的,比如
Python。

那比 C
语言版本不难的多。它首伊始入必需的模块(用于规范类别的sys和 pycurl模块)。接下来,它定义
write 缓冲区(wr_buf)。像 C 程序中相同,作者声美素佳儿(Friso)个 write_data函数。注意,该函数只有3个参数:从
HTTP 服务器中读取的多寡缓冲区。笔者将该缓冲区连接到全局 write
缓冲区。main函数首先成立一个 Curl句柄,然后使用 setopt办法为传输定义 URL和 WRITEFUNCTION。它调用 perform措施运行传输并关闭句柄。最终,它调用 main函数,并将 write
缓冲区提交到 stdout。注意,在那种气象下,您不必要错误上下文指针,因为你使用了
Python 字符串连接,那正是说您不会动用大小固定的字符串。

回页首

结束语

本文仅仅不难介绍了
libcurl,介绍了它援助的多种商业事务和言语。希望那能够突显它什么轻松营造利用应用层协议(如
HTTP)的应用程序。libcurl 网址(见 参考资料)提供了过多演示和一蹴而就的文书档案。下三回开发
Web 浏览器、爬行器或别的有应用层协议需求的应用程序时,试试
libcurl。它必将能大大裁减您的支出时间,并找回编码的童趣。

参考资料

学习

  • cURL是二个命令行工具和库,完成了各样客户端协议。它帮助12 种以上的协议,包罗 FTP、HTTP、Telnet
    以及其余安全变体。许多平台上都能找到 cU科雷傲L,包含 Linux、AIX、BSD 和
    Solaris,它援助 30 多样语言。

  • PycURL是 libcurl API
    之上的一个薄层,PycUKugaL 速度尤其快。使用 PycUXC90L,您能够动用 libcurl
    库开发 Python 应用程序。

  • 说起应用程序灵活性,您能够在 “用 Guile
    编写脚本

    中理解越多关于将脚本功效集成到应用程序的剧情。

  • 要听取有关软件开发职员的诙谐采访和座谈,请查看 developerWorks
    互联网播放

  • 问询最新的 developerWorks 技巧活动 和 网络广播

  • 在 Twitter 上跟随 developerWorks

  • 查看近来将在全世界举行的面向 IBM
    开放源码开发人员的研究切磋会、交易展览、网络播放和其余 活动

  • 访问 developerWorks 开源专区赢得丰裕的
    how-to 音讯、工具和种类更新,帮衬你用开放源码技术拓展开发,并与 IBM
    产品组合使用。

  • 查阅免费的 developerWorks On demand
    演示
    ,观望并明白IBM 及开源技术和制品效果。

获得产品和技能

相关文章