社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 银行

  • 64530阅读
  • 34回复

http库,ftp库,internet协议库资料汇总-libcurl,curl等

级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
— 本帖被 usidc5 设置为精华(2010-07-29) —
cURL 是一个命令行工具,可以对文件传输使用许多协议,包括 HTTP、FTP、Secure Copy (SCP)、Telnet 等等。但是,除了可以用命令行通过 Internet 与端点对话外,还可以使用 libcurl 编写简单或复杂的程序,以自动化执行应用层的协议任务。本文将介绍 cURL 命令行工具,然后向您展示如何使用 libcurl 以及 C 和 Python 构建一个 HTTP 客户端。

开发 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
图 1. 网络堆栈和 libcurl 

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 [url]www.exampledomain.com[/url]
  % Total% Received % Xferd  Average SpeedTimeTime TimeCurrent 
 Dload  UploadTotal   SpentLeftSpeed 
 100 43320  100 433200 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 SpeedTimeTime TimeCurrent 
 Dload  UploadTotal   SpentLeftSpeed 
 100 433200 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, "[url]www.exampledomain.com"[/url] ); 
  /* 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 应用程序。
关键词: http 代码 编程 curl
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 沙发  发表于: 2010-07-01
libcurl入门
libcurl库是一个实现了各种客户端协议的网络编程库。目前它支持12种以上的协议,包括 FTP、HTTP、Telnet以及其他安全变体。

如果您有 10 年以上的脚本语言经验,您就会注意到它们的标记有很大的变化。Python、Ruby、Perl 等这些脚本语言不仅包含套接字层(C 或 C++ 中也有),还包含了应用层协议 API。这些脚本语言合并了高级功能,可以创建 HTTP 服务器或客户端。libcurl 库为 C 和 C++ 之类的语言添加了类似的功能,但是它可以在不同的语言之间移植。在所有它支持的语言中都能找到与 libcurl 相当的行为,但是由于这些语言的差异很大(设想一下 C 和 Scheme),提供这些行为的方式也很不相同。

libcurl 库以 API 的形式封装各种客户端协议,因此它可以被高级语言使用(如今已超过 30 种)。下面的示例研究使用 C 构建的简单 HTTP 客户端(适合构建 Web 爬行器)。

基于 C 的 HTTP 客户端
C API 在 libcurl 功能上提供了两个 API。easy 接口是一个简单的同步 API(意味着当您使用请求调用 libcurl 时,将能够满足您的请求,直到完成或发生错误)。多接口可以进一步控制 libcurl,您的应用程序可以执行多个同步传输,并控制 libcurl 何时何地移动数据。

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

使用 libcurl easy 接口的 C HTTP 客户端

#include

#include

#include


#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 ");
return 0;
}

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

/* 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) ", ret, wr_error );

/* Emit the page if curl indicates that no errors occurred */
if ( ret == 0 ) printf( "%s ", 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 数据被提取,它也可以丢弃该数据。这就是从网站将文件读取到内存的相对简单的方法。
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 板凳  发表于: 2010-07-01
libcurl编程流程

首先,调用函数curl_global_init()来初始化库函数;
调用curl_easy_init()来初始化一个句柄,得到一个easy interface型指针;
接着,再调用curl_easy_setopt来设置将要访问的网络地址,当然还有许多其它的选项可以设置,这是libcurl编程的重点。

返回的数据怎样传给客户端应用程序呢?
先自己写一个回调函数,然后把这个回调函数通过curl_easy_setopt设置到libcurl库里。再指定是什么的数据格式接收,当libcurl库返回数据时就会回调设置的函数。
定义回调函数:
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
设置回调函数
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);
设置回调函数接收的数据格式
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);
通过调用curl_easy_perform来连接远程的网站,开始协议相关的操作,libcurl库启动下载或上传数据。

libcurl curl_easy_setopt()说明
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

CURLOPT_VERBOSE
设置这个选项的参数为1libcurl会显示出一些操作的详细信息。这对于libcurl和协议的调试和理解很有帮助。

CURLOPT_HTTPHEADER
构造HTTP头部字段,或代替现有字段(从而移除已有字段)。该选项传递一个指针,这个指针指向HTTP请求中传给server的头部字段链表(linked list)。用curl_slist_append(3)来创建头部字段listcurl_slist_free(3)用来清除list 。例如:增加User-Authertication这个头部字段。
使用libcurl设置HTTP头部字段的方法:
#include <curl/curl.h>
Struct curl_slist *slist = NULL;
Slist = curl_slist_append(slist, “Connection: Keep-Alive”); //http长连接
Curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist);
Curl_easy_perform(handle);
Curl_slist_free_all(slist);


CURLOPT_PUT/CURLOPT_UPLOAD
设置这个选项为1,让libcurl使用HTTP PUT来传输数据。从7.12.1版本开始,使用CURLOPT_UPLOAD来代替CURLOPT_PUT。使用这个选项还要通过CURLOPT_READDATA  CURLOPT_INFILESIZE来设置要传输的数据。

CURLOPT_READDATA
设置传递给读函数的数据指针。如果使用了 CURLOPT_WRITEFUNCTION 参数可以使用这个指针作为输入,如果没有使用CURLOPT_WRITEFUNCTION, 则必需给出一个FILE*类型指针, libcurl会将其传递给fwrite()
7.9.7版本之前,这个选项叫CURLOPT_INFILE

CURLOPT_INFILESIZE
当向远程站点上传文件时,这个选项用来设置上传文件的大小。

CURLOPT_POST
这个选项设置为1,告知libcurl执行HTTP POST操作。
默认libcurl会使用"Content-Type: application/x-www-form-urlencoded"头部字段,你也可以用CURLOPT_HTTPHEADER选项来更改这个字段。使用HTTP1.1POST方法意味着使用"Expect: 100-continue"字段,你也可以用CURLOPT_HTTPHEADER来取消这个字段。
可以设置CURLOPT_READFUNCTION CURLOPT_READDATA选项来为POST提供数据,同时,不能再设置CURLOPT_POSTFIELDS选项。当使用callback函数来提供数据时,一定要使用大块数据传输编码(chunked transfer-encoding)或者用CURLOPT_POSTFIELDSIZE CURLOPT_POSTFIELDSIZE_LARGE选项设置数据大小。chunked transfer-encoding可以用CURLOPT_HTTPHEADER来设置字段。
如果使用了POST请求方法,想要用同一个handleGETHEAD,必须用CURLOPT_NOBODY CURLOPT_HTTPGET选项来设置新的请求方法。

CURLOPT_WRITEFUNCTION
设置指向回调函数的指针,回调函数原型如下:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
libcurl接收到要保存的数据时调用此函数因此该函数多作数据保存的功能,如处理下载文件。ptr所指数据大小为 size*nmemb. 返回实际处理的数据大小,如果返回值不等于传递给函数的数据大小,则报错,并返回CURLE_WIRTE_ERROR
如果此选项的参数设置为NULL, 则会调用默认的函数,将数据写入到FILE*(CURLOPT_WRITEDATA 给出)
此回调函数会尽量处理更多数据,但是传递给回调函数的数据最大值定义在curl.h文件中。

CURLOPT_WRITEDATA
7.9.7版本以前,这个选项叫CURLOPT_FILE。该选项设置一个数据指针传递给函数。如果使用了 CURLOPT_WRITEFUNCTION 参数可以使用这个指针作为输入,指明CURLOPT_WRITEFUNCTION函数的stream指针的来源。如果没有使用CURLOPT_WRITEFUNCTION, 则必需给出一个FILE*类型, libcurl会将其传递给fwrite()。如:
FILE *fp;
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
   int written;

   written = fwrite(ptr, size, nmemb, (FILE *)fp);
    return written;
}


CALLBACK OPTIONS
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
CURLOPT_HEADERFUNCTIONCURLOPT_HEADERDATA
回调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb, void *stream); libcurl一旦接收到http 头部数据后将调用该函数。CURLOPT_WRITEDATA 传递指针给libcurl,该指针表明CURLOPT_HEADERFUNCTION 函数的stream指针的来源。

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指针来源。

HTTP OPTIONS
CURLOPT_POSTFIELDS
作用:描述传输的数据,必须确保传输的数据服务器可以解析,libcurl不会转化或encode,但是大部分服务器假定这些数据是url-encoded,
此选项使用后POST是一个application/x-www-form-urlencoded类型。 

CURLOPT_COOKIEJAR
作用:在关闭链接的时候把cookie写入指定的文件
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "/tmp/cookie.txt");

CURLOPT_COOKIEFILE
作用:取用现有的cookie,而不重新得到cookie
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");

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


参考网站:
[1]各种HTTP/FTP客户端开发库http://blog.csdn.net/heiyeshuwu/archive/2007/07/15/1691904.aspx
[2]Libcurl编程http://www.miidoo.cn/info_detail-227.html
[3]Libcurl编程手册及代码实例
http://www.maycode.com/index.php/linux/54-linuxdevelop/1151-curl.html
[4]Simplify Network Programming with libCURL
http://www.linuxdevcenter.com/pub/a/linux/2005/05/05/libcurl.html
[5]libcurl noteHttp应用)API介绍http://blog.chinaunix.net/u2/61797/article_82446.html
[6]libcurl使用的简单例子http://blog.chinaunix.net/u/27904/showart_462499.html
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 地板  发表于: 2010-07-01
在Dev-C++ 开发环境中使用 libcurl 函数库

第一步:在Dev-C++ 开发环境中安装 libcurl 函数库
    启动 Dev-C++ ,然后在 Dev-C++ 选择“工具[T]→检查更新[C](Z)...”,
    在WebUpdate窗口中,Select devpak server 选择 “devpaks.org Community Devpaks”,然后单击“Check for updates”,安装以下开发包:zlib 1.2.3、openss 0.9.8、libcurl 7.14.0
第二步:添加curl到连接器
    新建 curltest工程(控制台程序),然后在 Dev-C++ 的菜单中:工程→工程属性→参数→连接器 中加入 -lcurldll
第三步:添加测试程序
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
int main(int argc, char *argv[])
{
    
  char POST[255] = "" ;
  CURL *curl;
  CURLcode res;
    
  curl = curl_easy_init();
    
  sprintf(POST,"ei=UTF-8&p=%s",argv[1]);
    
  curl_easy_setopt(curl, CURLOPT_URL, "tw.dictionary.yahoo.com/search");
  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, POST);
  res = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
  return 0;
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
第四步:编译运行
  1. 从Dev-C++ 的安装目录的bin目录下拷贝libcurl.dll、libeay32.dll、libssl32.dll、zlib1.dll到编译好的程序目录下;
  2. 在命令行下如下运行:
      curltest.exe blizzard > result.html
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 4楼 发表于: 2010-07-01
通过libcurl使c++与javaweb应用配合
比如实现以个http的get方法,比如 http://www.baidu.com/s?wd=test 
注意在下载vc版库的有可能会少一个zlib1.dll的库,注意下载。 
代码示例: 
CURL * curl = curl_easy_init(); 
int ct = -1; //状态码记录 
        Ret = 0; 
if(curl) { 
CURLcode res; 
res = curl_easy_setopt(curl, CURLOPT_URL, "http://www.baidu.com/s?wd=test"); 
res = curl_easy_setopt(curl, CURLOPT_TIMEOUT,6);//6秒request超时 
res = curl_easy_perform(curl); 

if(CURLE_OK == res) { 
res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &ct); 
}else 

Ret = 1; 

//always cleanup 
curl_easy_cleanup(curl); 

libcurl 实现了很多平台。非常适合开发基于http等协议的接口。
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 5楼 发表于: 2010-07-01
在Windows Visual C++ 6.0/7.0下编译带ssl的curl库
编译libcurl with SSL:
1. 安装Perl:ActivePerl-5.8.0.806-MSWin32-x861.msi

2. 编译OpenSSL:(Windows/VC下编译成DLL)

a)         下载openssl,目前版本是:openssl-0.9.8g

b)        解压,比如:D:\.

c)        cd d:\openssl-0.9.8g

d)        perl Configure VC-WIN32

e)         ,或者ms\do_ms.bat、ms\do_nasm.batms\do_masm.bat

f)         到VCStudio的VC98(VC6,在.Net下是VC7)目录,运行:vcvars32.bat

g)        回到d:\openssl-0.9.8g,运行:nmake -f ms\ntdll.mak

h)        如果成功的话,会在out32dll目录下生成libeay32.dll, libeay32.lib, ssleay32.dll, ssleay32.lib

在编译的时候,可能会出现以下问题:

Assembling: .\crypto\sha\asm\sha512-sse2.asm .\crypto\sha\asm\sha512-sse2.asm(29) : error A2006: undefined symbol : XMMWORD

这是因为:.\crypto\perlasm\x86ms.pl中对masm的版本定义不对,OpenSSL网站上给出一个此文件的补丁:

openssl/crypto/perlasm/x86ms.pl     1.18.2.3 -> 1.18.2.4

--- x86ms.pl    2007/07/19 10:45:03 1.18.2.3

+++ x86ms.pl    2007/10/21 14:15:40 1.18.2.4

@@ -339,8 +339,17 @@

sub main'file_end

   {

   # try to detect if SSE2 or MMX extensions were used...

-   if (grep {/\b[x]?mm[0-7]\b,/i} @out) {

-       grep {s/\.[3-7]86/\.686\n\t\.XMM/} @out;

+   my $xmmheader=<<___;

+.686

+.XMM

+IF \@Version LT 800

+XMMWORD STRUCT 16

+   DQ 2 dup (?)

+XMMWORD ENDS

+ENDIF

+___

+   if (grep {/\b[x]?mm[0-7]\b/i} @out) {

+       grep {s/\.[3-7]86/$xmmheader/} @out;

       }

   push(@out,"_TEXT\$ ENDS\n");

   push(@out,"END\n");

但是仍然不对,所以干脆用NASM,回退到步骤e),运行ms\do_nasm.bat,然后依然按照下面的步骤进行。

3. 编译Libcurl:

a)         下载curl源代码,当前版本是curl-7.17.1

b)        解压

c)        到VCStudio的VC98(VC6,在.Net下是VC7)目录,运行:vcvars32.bat。(由于安装OpenSSL的时候已经做过,这步可省略)

d)        添加环境变量:OPENSSL_PATH=D:\openssl-0.9.8g

e)         到curl目录下,运行nmake vc-ssl-dll

f)         成功,则在.\lib下生成libcurl.lib。

g)        要得到libcurl.dll,可以运行.\lib\curllib.dsw,这是一个Visual Studio 6.0的工程,编译成功后可在.\lib\Debug下生成libcurl.dll。

其中,可能出现如下错误:

…\lib\ldap.c(49) : fatal error C1189: #error : Your Platform SDK is NOT sufficient for LDAP support! Update your Platform SDK, or disable

LDAP LDAP support!

原因是在ldap.c中会出现# include <winldap.h>,将winldap.h所在目录加到工程的project->Setting->C/C++->Category:Preprocessor->Additional include Directories中去即可。

另外,OpenSSL和Curl的include目录openssl和curl分别在各自主目录的inc32和include下。在编程时转移到资源目录或者直接include即可。
有关curl的资料可以在http://curl.haxx.se找到。
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 6楼 发表于: 2010-07-01
在windows环境下编译libcurl库

Download Microsoft Platform SDK
========================================================
    http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en
    Install it

Download Zlib Source
========================================================
    from http://www.zlib.net/
    http://www.zlib.net/zlib123.zip

Build Zlib
========================================================
    Use Visual C++ 6
    zlib123\projects\visualc6\zlib.dsw

Download Openssl Source
========================================================
    from http://www.openssl.org/source/
    http://www.openssl.org/source/openssl-0.9.8g.tar.gz

Build Openssl
========================================================
    maybe need to install active perl
    http://lccnc.skycn.com/down/ActivePerl-5.8.8.822-MSWin32-x86-280952.zip
    # run build shell
    cd openssl-***
    ms\32all.bat

Download Curl Source
========================================================
    from http://curl.haxx.se/
    http://curl.haxx.se/download/curl-7.18.1.zip

Build Curl
========================================================
    1. Pre Build
   
    a. create bat file for debug
    call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
    set CFG=debug-dll-ssl-dll-zlib-dll
    set OPENSSL_PATH=D:\svn_work\MDS\USS\trunk\openssl-0.9.8g
    set ZLIB_PATH=D:\svn_work\MDS\USS\trunk\zlib123-dll
    nmake -f Makefile.vc6
    b. create bat file for release
    call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
    set CFG=release-dll-ssl-dll-zlib-dll
    set OPENSSL_PATH=D:\svn_work\MDS\USS\trunk\openssl-0.9.8g
    set ZLIB_PATH=D:\svn_work\MDS\USS\trunk\zlib123
    nmake -f Makefile.vc6
    c. save shell code to bat file
    Save to : curl-***\lib\build.bat
    d. modify curl-***\lib\Makefile.vc6
    Find
        CFLAGS     = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
    set as
        CFLAGS     = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL  /I"C:\Program Files\Microsoft Platform SDK\Include"
    e. copy zlib123\projects\visualc6\Win32_DLL_Release\zlib1.lib to curl-7.18.1\lib\zdll.lib

    2. Build
    cd curl-***\lib
    build.bat
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 7楼 发表于: 2010-07-01
curl c/c++ api接口使用例程

来源:http://bbs.chinaunix.net/viewthread.php?tid=586014
前两天看到有人求客户端socket 发HTTP包的代码,受flw版主启发找了一些perl的资料,不过对perl 还是不太熟悉。也没有深入的 研究。无意中发现了libcurl.so 这个库。去google上搜索发现它是处理客户端发送HTTP请求的库 以及可以处理web服务器回送回来的 包。研究了两天将研究的成果,共享出来给大家一起研究。 

参考:http://curl.haxx.se/  这是curl开发者的首页。 

利用libcurl.so库 我们能轻松的连接某个web站点。获得某个首页的html代码 或者是http 请求的头部。 还可以提交表单, 
此外它还支持ftp,https, 

/usr/include/curl/curl.h 中。 

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类型的指针.


 下面来看一个简单的例子: 
用来获得某个主页的html代码 


[pre]#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;

}[/pre]

编译: gcc -o 001 -Wall 001.c -lcurl 

我们来获得www.chinaunix.net 主页的html代码 

./001 www.chinaunix.net

再来看一个例子: 
实际编程时 我们未必只显示出来.我们的目的是要对获得html代码做相应的处理.比如检验关键字,发现重要信息等等. 

那么我们就需要把获得的html代码存入相应的文件中.看下面一个例子 


[pre]
#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);

}[/pre]

gcc -o 002 -Wall 002.c -lcurl 
./002 www.chinaunix.net 
这个例子就将html代码保存在了www.chinaunix.net文件中了.

此外还可以获得http报文的头部 post表单 等等. 这里就不详细的介绍了. 具体的可以man curl_easy_setopt 
(要用到一个重要的结构体,HttpPost) 



下面看一个从ftp站点下载文件的例子. 



[pre]#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;

}[/pre]

gcc -o 003 -Wall 003.c -lcurl 
./003      fei.gif 


我有个匿名的ftp的网址 将目录下的fei.gif 保存到本地 也叫fei.gif 


此外还有curl_escape curl_unescape函数用来转换 汉字成 %XX 这种类型.以及转换回来.如果要下载带有汉字的文件.先要调用将字符串转换一下. 

curl 库 还有好多功能. 有待大家来挖掘.


说明:在gcc编译的时候记得加上 -lcurl
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 8楼 发表于: 2010-07-01
常用http库,ftp库介绍
网页抓取和ftp访问是目前很常见的一个应用需要,无论是搜索引擎的爬虫,分析程序,资源获取程序,WebService等等都是需 要的,自己开发抓取库当然是最好了,不过开发需要时间和周期,使用现有的Open source程序是个更好的选择,一来别人已经写的很好了,就近考验,二来自己使用起来非常快速,三来自己还能够学习一下别人程序的优点。


闲来无事,在网上浏览,就发现了这些好东西,特别抄来分享分享。主要就是libwww、libcurl、libfetch 这三个库,当然,还有一些其他很多更优秀库,文章后面会有简单的介绍。


【libwww】
好像很复杂,略.


【libcurl】


官方网站:http://curl.haxx.se/libcurl
更多特点:http://curl.haxx.se/docs/features.html
运行平台:Unix/Linux,Windows(Windows上貌似也有实现)


以下资料来源:http://blog.csdn.net/hwz119/archive/2007/04/29/1591920.aspx


Libcurl为一个免费开源的,客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP,跨平台,支持Windows,Unix,Linux等,线程安全,支持Ipv6。并且易于使用。


http://curl.haxx.se/libcurl/


http://curl.haxx.se/libcurl/ 下载一个稳定的版本,注意选择OS。


编译libcurl


下载下来的是源码包,需要编译。


解压zip文件,进入curl-7.14.0\lib目录(我下载的是7.14.0)。


编译Debug版本。新建一个批处理bat文件,如buildDebug.bat,内容如下:


call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"


set CFG=debug-dll-ssl-dll-zlib-dll


set OPENSSL_PATH=E:\SSL\openssl-0.9.7e


set ZLIB_PATH=E:\zip\zlib123


nmake -f Makefile.vc6


其输出:libcurld_imp.lib, libcurld.dll


编译Release版本。新建一个批处理文件BuildRelease.bat,内容如下:


call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"


set CFG=release-dll-ssl-dll-zlib-dll


set OPENSSL_PATH=E:\SSL\openssl-0.9.7e


set ZLIB_PATH=E:\zip\zlib123


nmake -f Makefile.vc6


其输出:libcurl_imp.lib, libcurl.dll


上面编译的是libcurl的 dll,使用OpenSSL Dll版本和Zlib Dll版本。如果没有,可以从www.openssl.org 或者http://www.zlib.net/ 下载。


如果需要编译其他版本,可查看Makefile.vc6,设定相应的CFG 参数即可。


商业软件使用libcurl时,只需要包含其copywrite声明即可。


Sample


#include <stdio.h>
#include "../curl-7.14.0/include/curl/curl.h"
#pragma comment(lib, "../curl-7.14.0/lib/libcurl_imp.lib")


int main(void)
{
   curl = curl_easy_init();
if(curl) {


     CURLcode res;    
     res = curl_easy_setopt(curl, CURLOPT_PROXY, "Test-pxy08:8080");
     res = curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
     res = curl_easy_setopt(curl, CURLOPT_URL, "http://www.vckbase.com");
     res = curl_easy_perform(curl);


    if(CURLE_OK == res) {
      char *ct;
      /**//* ask for the content-type */
      /**//* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
       res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);


      if((CURLE_OK == res) && ct)
         printf("We received Content-Type: %s ", ct);
     }


    /**//* always cleanup */
     curl_easy_cleanup(curl);
   }
return 0;
}


【libfetch】
官方网站:http://libfetch.darwinports.com/ 
更多信息:http://www.freebsd.org/cgi/man.cgi?query=fetch&sektion=3
运行平台:BSD


以下资料来源:http://bbs.chinaunix.net/viewthread.php?tid=105809


前几天无双老大在FB版介绍了一下CU的巨猛的法老级灌水大师,小弟于是说要编个程序自动来灌,哈哈昨晚有所突破,找到一个很好的库,先介绍给各位大鱼小虾们,不过可别真的拿它来灌水啊,否则我被这里的班长们砍死以后的冤魂可要来算帐的喔!    
这是在FreeBSD里找到的一个库:libfetch,源代码在/usr/src/lib/libfetch里,它对http和ftp协议进行了封装,提供了一些很容易使用的函数,因为昨天刚看到,还没仔细研究,我试了一个用http取网页的函数,示例如下:


#include <stio.h>
#include 
#include 


#include "fetch.h"


const char * myurl = "http://qjlemon:aaa@192.169.0.1:8080/test.html";


main()
{
         FILE * fp;
        char buf[1024];


         fp = fetchGetURL(myurl, "";
        if (!fp) {
                 printf("error: %s ", fetchLastErrString);
                return 1;
         }
        while (!feof(fp)) {
                 memset(buf, 0, sizeof(buf));
                 fgets(buf, sizeof(buf), fp);
                if (ferror(fp))
                        break;
                if (buf[0])
                         printf("%s", buf);
                else
                        break;
         }
         fclose(fp);
         fp = NULL;
}




这里最重要的就是fetchGetURL函数,它按指定的URL来取文件,比如URL
是以http开头的,这个函数就知道按http取文件,如果是ftp://,就会按ftp取文件,还可以指定用户名和口令。
如果文件被取到,它会返回一个FILE指针,可以象操作普通的文件一样把网页的内容取出来。
另外这个库还提供了一些函数,可以对网络操作进行更为精细的控制。
当然最有用的是还是几个PUT函数,想要灌水就得用这个哟!哈哈哈!


【其他相关HTTP/FTP客户端库】
资料来源:http://curl.haxx.se/libcurl/competitors.html


Free Software and Open Source projects have a long tradition of forks and duplicate efforts. We enjoy "doing it ourselves", no matter if someone else has done something very similar already.


Free/open libraries that cover parts of libcurl's features:


libcurl (MIT)


a highly portable and easy-to-use client-side URL transfer library, supporting FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TELNET, DICT, FILE, TFTP and LDAP. libcurl also supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP form based upload, proxies, cookies, user+password authentication, file transfer resume, http proxy tunnelling and more!


libghttp (LGPL)


Having a glance at libghttp (a gnome http library), it looks as if it works rather similar to libcurl (for http). There's no web page for this and the person who's email is mentioned in the README of the latest release I found claims he has passed the leadership of the project to "eazel". Popular choice among GNOME projects.


libwww (W3C license) comparison with libcurl


More complex, and and harder to use than libcurl is. Includes everything from multi-threading to HTML parsing. The most notable transfer-related feature that libcurl does not offer but libwww does, is caching.


libferit (GPL)


C++ library "for transferring files via http, ftp, gopher, proxy server". Based on 'snarf' 2.0.9-code (formerly known as libsnarf). Quote from freshmeat: "As the author of snarf, I have to say this frightens me. Snarf's networking system is far from robust and complete. It's probably full of bugs, and although it works for maybe 85% of all current situations, I wouldn't base a library on it."


neon (LGPL)


An HTTP and WebDAV client library, with a C interface. I've mainly heard and seen people use this with WebDAV as their main interest.


libsoup (LGPL) comparison with libcurl


Part of glib (GNOME). Supports: HTTP 1.1, Persistent connections, Asynchronous DNS and transfers, Connection cache, Redirects, Basic, Digest, NTLM authentication, SSL with OpenSSL or Mozilla NSS, Proxy support including SSL, SOCKS support, POST data. Probably not very portable. Lacks: cookie support, NTLM for proxies, GSS, gzip encoding, trailers in chunked responses and more.


mozilla netlib (MPL)


Handles URLs, protocols, transports for the Mozilla browser.


mozilla libxpnet (MPL)


Minimal download library targeted to be much smaller than the above mentioned netlib. HTTP and FTP support.


wget (GPL)


While not a library at all, I've been told that people sometimes extract the network code from it and base their own hacks from there.


libfetch (BSD)


Does HTTP and FTP transfers (both ways), supports file: URLs, and an API for URL parsing. The utility fetch that is built on libfetch is an integral part of the FreeBSD operating system.


HTTP Fetcher (LGPL)


"a small, robust, flexible library for downloading files via HTTP using the GET method."


http-tiny (Artistic License)


"a very small C library to make http queries (GET, HEAD, PUT, DELETE, etc.) easily portable and embeddable"


XMLHTTP Object also known as IXMLHTTPRequest (part of MSXML 3.0)


(Windows) Provides client-side protocol support for communication with HTTP servers. A client computer can use the XMLHTTP object to send an arbitrary HTTP request, receive the response, and have the Microsoft? XML Document Object Model (DOM) parse that response.


QHttp (GPL)


QHttp is a class in the Qt library from Troll Tech. Seems to be restricted to plain HTTP. Supports GET, POST and proxy. Asynchronous.


ftplib (GPL)


"a set of routines that implement the FTP protocol. They allow applications to create and access remote files through function calls instead of needing to fork and exec an interactive ftp client program."


ftplibpp (GPL)


A C++ library for "easy FTP client functionality. It features resuming of up- and downloads, FXP support, SSL/TLS encryption, and logging functionality."


GNU Common C++ library


Has a URLStream class. This C++ class allow you to download a file using HTTP. See demo/urlfetch.cpp in commoncpp2-1.3.19.tar.gz


HTTPClient (LGPL)


Java HTTP client library.


Jakarta Commons HttpClient (Apache License)


A Java HTTP client library written by the Jakarta project.
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 9楼 发表于: 2010-07-01
Linux下LibCurl编程


1         LibCurl简介
LibCurl是免费的客户端URL传输库,支持FTP,FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE ,LDAP等协议,其主页是http://curl.haxx.se/。Libcurl具备线程安全、IpV6兼容、易于使用的特点。本文档主要介绍LibCurl在http协议方面的应用。
1.1HTTP协议格式
说明:本节主要介绍http协议,若熟悉http协议者可不看。
Http(超文本传输协议)是分布式双向超媒体信息系统应用层协议,主要应用于WWW。通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。http消息(请求或者响应)消息的通用格式实质相同,这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。

起始行:请求消息中的的起始行称为请求行,由3个字段组成,它们定义请求的类型、URL和http版本,最后是回车和换行符。请求类型包括get、head、post、put、move等。响应消息中的的起始行称为,也由三个部分组成,http版本、状态码和状态短语,最后是回车和换行符。所有的Http消息题头
http头域:HTTP的头域按其所属性质包括通用头,请求头,响应头和实体头四个部分。通用头域允许出现在请求或者响应消息中,包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。请求头域只允许出现在请求消息中,响应头域只允许出现在响应消息中,实体头部分提供有消息文档主体信息,主要在响应消息中发送;但是请求消息(如post和put方法)也可以使用实体题头。
每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。下表为一个典型的请求消息,下面介绍常用头域:

GET http://download.microtool.de:80/somedata.exe HTTP/1.1
Host: download.microtool.de
Accept:*/*
Pragma: no-cache
Cache-Control: no-cache
Referer: http://download.microtool.de/
User-Agent:Mozilla/4.04[en](Win95;I;Nav)
Range:bytes=554554-

消息的第一行是请求行,“GET”表示我们所使用的HTTP动作,其他可能的还有“POST”等,GET的消息没有消息体,而POST消息是有消息体的,消息体的内容就是要POST的数据。后面http://download.microtool.de:80/somedata.exe就是我们要请求的对象,之后HTTP1.1表示使用的是HTTP1.1协议。
从第2行开始进入http头域,本例中共包括HostAcceptPragmaCache-ControlRefererUser-AgentRange
Host域:表示我们所请求的主机和端口
Accept域:表示我们所用的浏览器能接受的Content-type(一般包括image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword),
Pragma域:Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同。
Cache-Control域:Cache -Control指定请求和响应遵循的缓存机制。
Referer Referer 头域允许客户端指定请求ui的原资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,Referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。
User-Agent头域:User-Agent头域的内容包含发出请求的用户信息。
Range头域:Range头域可以请求实体的一个或者多个子范围,跟断点续传相关。例如,
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
但是服务器可以忽略此请求头,如果无条件GET包含Range,请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。

一个典型的响应消息格式如下:

HTTP/1.0200OK
Date:Mon,31Dec200104:25:57GMT
Server:Apache/1.3.14(Unix)
Content-type:text/html
Last-modified:Tue,17Apr200106:46:28GMT
Etag:"a030f020ac7c01:1e9f"
Content-length:39725426                             
Content-range:bytes554554-40279979/40279980

消息第一行为响应行,起格式为如下, 包括http版本、状态码和文本描述。

HTTP-Version SPStatus-CodeSP Reason-Phrase CRLF

HTTP -Version表示支持的HTTP版本,例如为HTTP/1.1。Status- Code是一个三个数字的结果代码。Reason-Phrase给Status-Code提供一个简单的文本描述。Status-Code主要用于机器自动识别,Reason-Phrase主要用于帮助用户理解。Status-Code的第一个数字定义响应的类别,后两个数字没有分类的作用。第一个数字可能取5个不同的值:
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求

响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和 Request-URI进一步的信息。响应头域包含Age、Location、Proxy-Authenticate、Public、Retry- After、Server、Vary、Warning、WWW-Authenticate。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头域,一般将会作为实体头域处理。
在上表中,从第二行开始进入http头域。包括DateServerContent-typeLast-modifiedEtagContent-lengthContent-range域。一些比较重要的头域包括:
Location域:Location响应头用于重定向接收者到一个新URI地址。
Content-Type属于实体头,用于向接收方指示实体的介质类型,指定HEAD方法送到接收方的实体介质类型,或GET方法发送的请求介质类型 Content-Range实体头
Content-length域:属于实体头,指明实体(文档)长度,表示实际传送的字节数。
Content-Range属于实体头,用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:

Content-Range:bytes-unitSP first-byte-pos-last-byte-pos/entity-legth

例如,传送头500个字节次字段的形式:Content-Range:bytes 0-499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),Content-Range表示传送的范围。
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
描述
快速回复

您目前还是游客,请 登录注册
如果您在写长篇帖子又不马上发表,建议存为草稿