`
dxx16dxx
  • 浏览: 13882 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

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

 
阅读更多

使用 cURL 和 libcurl 通过 Internet 进行对话
2010年09月10日
  Tim M. Jones, 顾问工程师, 
  2009 年 10 月 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,并提取底层传输和网络层协议的详细信息。 
  
  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 绑定: apt-get实用工具确保该过程满足所有的依赖关系。 在命令行中使用 cURL
  cURL 最开始是一个命令行工具,可以使用 Uniform Resource Locator (URL) 语法执行数据传输。考虑到它在命令行上的流行度,后来创建了一个可以在应用程序中生成这些行为的库。如今,命令行 cURL 是 cURL 库的包装器。本文首先研究 cURL 作为命令行的功能,然后深入探讨如何将它作为库使用。
  cURL 的两种常见用法是使用 HTTP 和 FTP 协议进行文件传输。cURL 为这些协议提供一个简单的接口。要使用 HTTP 从网站获取文件,只需告诉 cURL 您要将网页写入到其中的本地文件的文件名、网站的 URL 以及要获取的文件。让我们看一下清单 1 中的简单命令行示例。 注意,由于我指定了域而不是文件,我将获得根文件(index.html)。要使用 cURL 将该文件移动到 FTP 站点,可以使用 -T选项指定要上传的文件,然后提供 FTP 站点的 URL 以及文件的路径。 是不是很简单?学习了一些模式之后您会发现,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 语言示例。  #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\n"); return 0; } /* Tell curl the URL of the file we're going to retrieve */ curl_easy_setopt( curl, CURLOPT_URL, "www.exampledomain.com" ); /* Tell curl that we'll receive data to the function write_data, and * also provide it with a context pointer for our error return. */ curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void *)&wr_error ); curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_data ); /* Allow curl to perform the action */ ret = curl_easy_perform( curl ); printf( "ret = %d (write_error = %d)\n", ret, wr_error ); /* Emit the page if curl indicates that no errors occurred */ if ( ret == 0 ) printf( "%s\n", wr_buf ); curl_easy_cleanup( curl ); return 0; } 
  最上方是必需的 include文件,包括 cURL 根文件。接下来,我定义了两个用于传输的变量。第一个变量是 wr_buf,表示将在其中写入传入数据的缓冲区。wr_index表示缓冲区的当前写入索引。 转到 main函数,该函数使用 easy API 进行设置。所有 cURL 调用都通过维护特定请求状态的句柄进行操作。这称为 CURL指针引用。本例还创建一个特殊的返回码,称为 CURLcode。在使用任何 libcurl 函数之前,您需要调用 curl_easy_init获取 CURL句柄。接下来,注意 curl_easy_setopt调用的数量。它们为特定的操作配置句柄。对于这些调用,您提供句柄、命令和选项。首先,本例使用 CURLOPT_URL指定要获取的 URL。然后,它使用 CURL_WRITEDATA提供一个上下文变量(在本例中,它是内部的 write 错误变量)。最后,它使用 CURLOPT_WRITEFUNCTION指定数据可用时应该调用的函数。在启动 API 之后,API 将使用它读取的数据多次调用该函数。 要开始传输,调用 curl_easy_perform。它的工作是根据之前的配置执行传输。调用该函数时,在完成传输或发生错误之前该函数不会返回。main的最后一步是提交返回状态,提交页面读取,最后使用 curl_easy_cleanup清除(当使用句柄执行完操作后)。 现在看看 write_data函数。该函数是针对特定操作收到数据时调用的回调。注意,当您从网站读取数据时,将写入该数据(write_data)。将向回调提供一个缓冲区(包含可用数据)、成员数量和大小(缓冲中可用数据总量)、上下文指针。第一个任务是确保缓冲区(wr_buf)的空间足以写入数据。如果不够,它将设置上下文指针并返回 0,表示出现问题。否则,它将 cURL 缓冲区的数据复制到您的缓冲区,并增加索引,指向要写入的下一个位置。本例还终止字符串,稍后可以对其使用 printf。最后,它返回 libcurl 操作的字节数量。这将告诉 libcurl 数据被提取,它也可以丢弃该数据。这就是从网站将文件读取到内存的相对简单的方法。 基于 Python 的 HTTP 客户端
  本节提供的示例类似于基于 C 的 HTTP 客户端,不过它使用的是 Python。Python 是一种非常有用的面向对象的脚本语言,在原型化和构建生产软件方面非常突出。示例假设您较熟悉 Python,但使用不多,因此不要期望过高。 这个简单的 Python HTTP 客户端使用 pycurl,如清单 4 所示。 使用 Python 进行原型化
  原型化是 Python 的优势之一。它只需很少的代码就可以实现大量功能。使用 C 也许能获得更好的性能,但是如果您的目的是快速编码以证明某个概念,那么高级脚本语言是无可替代的,比如 Python。 这比 C 语言版本简单的多。它首先导入必需的模块(用于标准系统的 sys和 pycurl模块)。接下来,它定义 write 缓冲区(wr_buf)。像 C 程序中一样,我声明一个 write_data函数。注意,该函数只有一个参数:从 HTTP 服务器中读取的数据缓冲区。我将该缓冲区连接到全局 write 缓冲区。main函数首先创建一个 Curl句柄,然后使用setopt方法为传输定义 URL和 WRITEFUNCTION。它调用 perform方法启动传输并关闭句柄。最后,它调用 main函数,并将 write 缓冲区提交到 stdout。注意,在这种情况下,您不需要错误上下文指针,因为您使用了 Python 字符串连接,这就是说您不会使用大小固定的字符串。 结束语
  本文仅仅简单介绍了 libcurl,介绍了它支持的多种协议和语言。希望这能够展示它如何轻松构建使用应用层协议(如 HTTP)的应用程序。libcurl 网站(见 参考资料)提供了很多示例和有用的文档。下一次开发 Web 浏览器、爬行器或其他有应用层协议要求的应用程序时,试试 libcurl。它一定能大大减少您的开发时间,并找回编码的乐趣。 参考资料 cURL是一个命令行工具和库,实现了各种客户端协议。它支持 12 种以上的协议,包括 FTP、HTTP、Telnet 以及其他安全变体。许多平台上都能找到 cURL,包括 Linux、AIX、BSD 和 Solaris,它支持 30 多种语言。
  PycURL是 libcurl API 之上的一个薄层,PycURL 速度非常快。使用 PycURL,您可以使用 libcurl 库开发 Python 应用程序。
  说到应用程序灵活性,您可以在 "用 Guile 编写脚本" 中了解更多有关将脚本功能集成到应用程序的内容。
  要收听有关软件开发人员的有趣采访和讨论,请查看 developerWorks 网络广播。
  了解最新的 developerWorks 技术活动 和 网络广播。
  在 Twitter 上跟随 developerWorks。
  查阅最近将在全球举办的面向 IBM 开放源码开发人员的研讨会、交易展览、网络广播和其他 活动。
  访问 developerWorks 开源专区获得丰富的 how-to 信息、工具和项目更新,帮助您用开放源码技术进行开发,并与 IBM 产品结合使用。
  查看免费的 developerWorks On demand 演示,观看并了解 IBM 及开源技术和产品功能。
  使用 IBM 试用软件改进您的下一个开发项目,这些软件可以通过下载中心获得。
  下载 IBM 产品评估版 或 在 IBM SOA Sandbox 中研究在线试用版,开始使用来自 DB2??、Lotus??、Rational??、Tivoli??和 WebSphere??的应用程序开发工具和中间件产品。
分享到:
评论

相关推荐

    使用VC6编译-Curl和LibCurl+ssl+ssh2+zlib

    使用VC6编译-Curl和LibCurl+ssl+ssh2+zlib libcurl是一个跨平台的开源网络协议库,支持http, https, rtsp等多种协议 。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,...

    curl和libcurl的区别简介

    curl 和 libcurl 是两个在 IT 领域中用于文件传输和网络请求的重要工具,它们在功能上有所重叠但用途有所不同。 curl 是一个命令行工具,用户可以直接在终端中输入命令来执行文件传输任务。它支持众多的网络协议,...

    everything-curl http libcurl

    everything-curl http libcurl client 文档,积累了libcurl使用过程中各种使用方法

    go-curl, golang curl(libcurl) 绑定.zip

    go-curl, golang curl(libcurl) 绑定 curl 我的golang libcurl(curl) 绑定。请参阅./examples/directory~中的更多示例 !许可证转到curl许可在Apache许可下,版本 2.0 ( http://www.apache.o

    QTCreator 通过libcurl实现ftp和fts文件上传

    在本教程中,我们将探讨如何使用libcurl库在QTCreator中实现FTP和FTPS文件上传功能。 libcurl是一个开源的客户端URL传输库,支持多种网络协议,包括FTP、FTPS、HTTP、HTTPS等。这个库以其易用性和广泛的功能而受到...

    linux下编译安装libcurl(附使用示例)1

    在Linux环境下,libcurl是一个非常重要的库,它提供了在各种协议(包括HTTP、FTP、SMTP等)下进行网络数据传输的功能。这篇教程将详细介绍如何在Linux...学习和掌握libcurl的使用对进行Linux下的网络编程非常有帮助。

    mac平台curl库源码编译libcurl

    这个资源蓝本在libcurl源码+openssl : “http://download.csdn.net/detail/yq910902/9458278”当中。12年时候的编译文档,有一些不太适合现在的情况,编译文档做了一些修改。在reademe.txt当中有说明

    libcurl 使用vs2010编译的动态库和静态库(包含的debug和release版和头文件)

    本资源提供了使用Visual Studio 2010编译的libcurl动态库(dll)和静态库,以及对应的debug和release版本,同时包含了完整的头文件,便于开发者进行C++项目集成。下面将详细介绍libcurl的编译过程、使用方法以及如何...

    c++使用libcurl上传和下载资源

    上传资源通常涉及POST请求,使用`libcurl`可以通过`curl_easy_setopt`函数设置请求方法和数据。以下是一个简单的示例: ```cpp #include <curl/curl.h> #include void uploadFile(const std::string& url, const ...

    java通过jni调用libcurl,curl java

    libcurl主要功能就是用不同的协议连接和沟通不同的服务器~也就是相当封装了的sockPHP 支持libcurl(允许你用不同...PHP自带curl扩展,但java没有curl扩展,这个工程的目的,就是将libcurl进行封装,以jni的方式进行调用

    vc6.0 libCurl 简单使用

    这段代码中,`curl_global_init()`和`curl_global_cleanup()`用于初始化和清理libCurl全局环境,`curl_easy_init()`创建了一个新的会话,然后`curl_easy_setopt()`设置了请求的URL。`curl_easy_perform()`实际执行了...

    curl-7.79.1.rar_libcurl.lib源码,含教程说明

    源代码可以帮助我们深入理解CURL的工作原理,学习如何使用libcurl进行网络编程,以及定制和扩展CURL的功能。 "使用说明.txt"文件很可能是CURL库的安装和使用指南,它会包含编译libcurl的步骤、如何在项目中链接...

    windows+vs2019+debug+x64+libcurl

    注意,使用libcurl时需要处理错误,例如通过`curl_easy_strerror()`获取错误信息。另外,libcurl支持异步操作,如果你的应用需要处理多个并发请求,可以利用多线程或多会话功能。 对于HTTPS请求,libcurl默认使用...

    curl-libcurl

    **curl-libcurl**是Linux平台上广泛使用的开源网络通信库,主要用C++语言编写,它提供了丰富的功能,用于处理各种互联网协议,如HTTP、FTP、SMTP等。CURL库不仅适用于命令行工具,还常被集成到其他软件项目中,以...

    Qt+libcurl实现FTP文件上传和下载

    你可以参考这些资源来理解和实践如何在Qt项目中使用libcurl进行FTP操作。 总之,结合Qt和libcurl能帮助你构建功能完备的FTP客户端应用,提供稳定的文件上传和下载功能。理解这两个库的交互和libcurl的FTP接口是关键...

    openssl和libcurl的静态库(VS2008和VS2010编译)

    - 编写代码,调用libcurl API,如`curl_easy_init()`,`curl_easy_setopt()`和`curl_easy_perform()`进行网络请求。 5. **注意事项** - 编译过程中需注意版本兼容性,openssl、libcurl和Visual Studio的版本应...

    使用libcurl获取经过gzip压缩的网页文件

    通过以上步骤,我们可以使用libcurl有效地获取和处理经过gzip压缩的网页文件。结合提供的链接文章(http://blog.csdn.net/zengraoli/article/details/13623237),可以进一步学习libcurl的具体使用方法和技巧。同时...

    libcurl使用Https说明

    ...本篇文章将深入探讨如何利用libcurl进行安全的HTTPS通信。 ### 1.... libcurl是一个C语言编写的库...通过阅读《libcurl使用说明.doc》文档,你可以找到更多关于libcurl的具体用法和实例,进一步提升你的HTTPS编程能力。

    C++使用libcurl提供的API上传文件且Post表单数据

    首先,`con_test.cpp`是主要的源代码文件,它包含了使用libcurl进行文件上传和POST操作的具体实现。`StdAfx.cpp`和`StdAfx.h`是Visual Studio项目中的预编译头文件,用于提高编译速度。`con_test.dsp`和`con_test....

Global site tag (gtag.js) - Google Analytics