这个文档是小编在curl官网上使用谷歌翻译翻译的,详细信息看官网
描述
这是关于C程序中如何使用libcurl的简单概述,libcurl程序的使用需要通过以下5个方面libcurl-easy、libcurl-multi、libcurl-share、libcurl-url和libcurl-tutorial,通过这5个方面的学习,就可以熟练的掌握libcurl知识。当然libcurl可以被其他的语言使用,包括java、php等。
主要包括:全局环境变量、libcurl的easy传输和mulit传输、持久性连接、可移植性等。
在使用libcurl的过程中,有一个全局的环境变量需要注意,这个全局的环境变量是通过curl_global_init 函数创建的。在使用结束之后需要调用curl_global_cleanup函数释放。这个环境变量在使用时必须设置和维护,可参阅下面的全局常量。当然如果编译 libcurl 时支持多个 SSL 后端,则可以在 curl_global_init 之前调用函数curl_global_sslset来选择活动的 SSL 后端。
使用libcurl传输有两种方式:
1、使用easy接口传输,这个接口使用简单,用于单向传输。同步传输,一个进程就只有一个传输句柄。使用步骤:首先使用curl_easy_init创建一个“简单处理” 。之后使用curl_easy_setopt在该句柄中设置所需的一组选项。使用curl_easy_setopt设置的选项。它们将在每次重复使用此句柄时使用,更改选项或使用curl_easy_reset将它们全部重置。属性设置完成之后调用curl_easy_perform并让它执行传输。完成后,函数返回。 可以传输文件??
2、使用mulit接口传输,这个是一个多接口传输是一个异步传输,调用它并且在每次调用时只执行一小部分传输。如果您想在传输过程中或类似情况下做一些事情,这是完美的。多接口允许您在 libcurl 操作上进行 select(),甚至可以使用单个线程轻松同时下载多个文件。请参阅libcurl-multi手册页中的更多详细信息。
您可以让多个简单句柄共享某些数据,即使它们在不同的线程中使用。这个就是使用共享接口设置的,如libcurl-share手册页中所述。
当然除了以上一些功能还有其他功能:
curl_version_info()
获取详细的 libcurl(和其他使用的库)版本信息
curl_getdate()
将日期字符串转换为 time_t
curl_easy_getinfo()
获取有关已执行传输的信息
curl_formadd ()
帮助构建 HTTP 表单 POST
curl_formfree()
释放使用curl_formadd构建的列表
curl_slist_append()
建立一个链表
curl_slist_free_all()
释放整个 curl_slist
curl_url_set()
解析一个 URL
Libcurl 符号名称
libcurl 接口中的所有公共函数都以'curl_'(带有小写c)为前缀。您可以在库源代码中找到其他函数,但其他前缀表示这些函数是私有的,可能会在下一个版本中更改,恕不另行通知。
可移植性
libcurl在它编译和构建的任何平台上都完全相同。
线程
libcurl 是线程安全的,但也有一些例外。有关更多信息,请参阅libcurl-thread。
持久连接
持久连接意味着如果条件合适,libcurl 可以为多个传输重用相同的连接。
libcurl 将始终尝试使用持久连接。每当您使用curl_easy_perform或curl_multi_perform等时,libcurl 将尝试使用现有连接进行传输,如果不存在,它将打开一个新连接,以便在可能的后续调用curl_easy_perform或curl_multi_perform时重复使用。
为了让 libcurl 充分利用持久连接,您应该使用相同的句柄进行尽可能多的文件传输。
如果您使用简单接口并调用curl_easy_cleanup,libcurl 持有的所有可能打开的连接都将被关闭并忘记。
当您创建了多句柄并使用多接口时,连接池将保留在多句柄中,因此关闭和创建新的简单句柄以进行传输不会影响它们。相反,所有添加的简单句柄都可以利用单个共享池。
全局常量
1、为啥要是用全局常量???
libcurl 使用的常量有很多种,主要是通过它内部对其他库的使用,对于库加载器来说设置起来过于复杂。因此,程序必须在程序加载并运行后调用库函数才能完成库代码的设置。例如,当通过 GNU TLS 库为 SSL 功能构建 libcurl 时,该库中有一个详细的树来描述 SSL 协议。
2、全局常量如何设置???
在使用libcurl之前我们需要调动curl_global_init函数。这个函数会分配libcurl使用所需的资源(例如上面提到的 GNU TLS 树的内存),当然,有分配就会有释放,他的伴随函数curl_global_cleanup会释放他分配的一些资源。
构建使用 libcurl 的程序的基本规则是:
在程序启动后立即调用curl_global_init,并使用CURL_GLOBAL_ALL参数,此时它仍然只有一个线程,并且在它使用 libcurl 之前。在程序退出之前立即调用curl_global_cleanup,此时程序再次只有一个线程并且在最后一次使用 libcurl 之后。
3、为啥要在程序启动后立即调用curl_global_init函数。
实际上并不需要在程序的开头和结尾调用函数——这通常是最简单的方法。其实在程序运行时没有其他线程运行就可以调用这些函数。那这又是为什么?
其实这些全局常量函数不是线程安全的,因此当程序中有其他线程正在运行时,即使不调用它们。当时也没有其他线程使用 libcurl 。那我们也不能确定目前使用的全局常量是否在使用。因为有些函数在内部调用了其他库的类似函数,并且这些函数同样是线程不安全的。
当我们编写使用 libcurl 的代码不是主程序,而是程序的模块化部分(例如另一个库)时,全局常量就需要我们特别注意。作为一个模块,我们不知道是否有其他的库或者函数使用libcurl,更无法确定是否在程序的开头和结尾有设置全局环境变量。因此,我们的模块就需要自己的全局常量函数。这样,该模块在程序的开始和结束处具有控制权,并且有一个地方可以调用 libcurl 函数。如果程序中的多个模块使用 libcurl,它们都会分别调用 libcurl 函数,这是可能需要考虑另一个问题,这么多模块全都初始化全局变量,不会出现问题吗?其实这是没关系,因为程序中只有第一个curl_global_init和最后一个curl_global_cleanup会改变任何内容。(libcurl 使用静态内存中的引用计数)。
在 C++ 模块中,可以让构造函数调用curl_global_init和析构函数调用curl_global_cleanup并满足 libcurl 的要求。(警告:如果从 Windows DLL 初始化 libcurl,则不应从 DllMain 或静态初始化程序对其进行初始化,因为 Windows 在此期间持有加载程序锁,并且可能导致死锁。)
curl_global_init特性:
curl_global_init有一个参数,它告诉要设置全环境局常量哪些那些特性。为了使用除CURL_GLOBAL_ALL之外的参数(表示设置整个事物),您必须对 libcurl 的内部工作以及它所属的程序的特性有所了解。
全局环境常量的一个特性是内存分配器的标识。curl_global_init选择系统默认内存分配器,但我们也可以使用curl_global_init_mem提供您自己的内存分配器。但是没有办法在模块化程序中使用curl_global_init_mem—— 程序中可能使用 libcurl 的所有模块都必须就一个分配器达成一致。
libcurl 中有一个故障保护功能,就是当我们没有使用curl_global_init函数初始化全局环境变量的时候,函数curl_easy_init会自行设置环境。它为此获得的资源在程序退出时由操作系统自动释放。此故障保护功能的存在主要是为了向后兼容,因为曾经有一段时间不存在全局函数。因为它只在最简单的程序中就足够了,所以不建议任何程序依赖它。