http协议之libcurl库的编译和调用

libcurl简介

libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。

libcurl的官网              库下载

libcurl的使用

  • 调用curl_global_init()初始化libcurl,(就像初始化套接字)
  • 调用curl_easy_init()函数得到 easy interface型指针(这个指针用来各种配置)
  • 调用curl_easy_setopt()设置传输选项(通过调用curl_easy_setopt这个函数来对指针进行各种配置,比如:请求的方式)
  • 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务
  • 调用curl_easy_perform()函数进行访问请求
  • 调用curl_easy_cleanup()释放内存

libcurl等第三方库的通用方法: 

点击下载libcurl库

 下载完成后拷贝到Ubuntu文件夹下,解压  tar vxf curl-7.71.1.tar.bz2   ,进入文件夹

那么如何使用这种开源的压缩包呢?这个文件夹下面有一个README文件夹,里面有对库的一些说明,不论用到的是什么库,我们都可以去阅读README学习如何使用,如下图所示 

Curl是一个命令行工具,用于传输使用URL指定的数据语法。通过阅读curl来了解如何使用curl.1手册页或手册文档。通过阅读install了解如何安装Curl文档。

Libcurl是curl用来完成它的工作的库。它很容易可由您的软件使用。阅读libcurl.3手册页如何学习!

您可以在FAQ文档中找到我们最常见问题的答案。

研究复制文件中的分发条款和类似条款。如果你分配Curl二进制文件或其他包含libcurl的二进制文件,您可能会喜欢LICENSE-MIXING文档。

所有这些文档和更多文件都可以在docs/目录中找到。

下面的内容就不贴上来了,可以通过翻译软件自行阅读。

通过阅读README我们进入到docs这个文件夹,这个文件夹是对RADME的一个补充,在这个文件夹下面我们会看到README里面提到的curl1.1这个API相关的手册,还有INSTALL(这个一定要看,有时候他会和README都放在解压后的文件夹里面,有时候会放在docs里面)。

打开INSTALL.cmd文件,里面有介绍如何安装编译后的libcurl库,下面可以看到在UNIX环境下面如何进行安装,如下图所示,./config就是配置的一个东西,就是将库安装到哪里,若后面不跟任何的参数,就是默认安装(可能安装在/usr/lib或者/usr/include下面)。make就是编译的意思,make install就是将编译后的东西拷贝到根目录的相关文件夹下面。如果默认安装的话可能需要root权限因为:默认可能安装在/usr/lib或者/usr/include下面,而访问这两个文件夹需要root权限。

./configure --help可以查看configure都支持哪些功能参数,其中下面的HOST这个指令可以指定交叉编译的编译器(若不指定交叉编译工具默认使用gcc编译工具)。  

指定位置配置文件  ./configure --prefix=$PWD/_install

编译  make

安装  make  install

调用libcurl库访问百度主页并将数据保存到文件中:

http  GET操作代码

#include <stdio.h>
#include <curl/curl.h>
#define true 1
#define false 0
typedef unsigned int bool;
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;
        }
}
int main(void)
{
        getUrl("/tmp/get.html");
}

使用指令: gcc demo1.c -o demo1 -I ~/httplibcurl/curl-7.71.1/_install/include -L ~/httplibcurl/curl-7.71.1/_install/lib/ -lcurl 进行编译,-I是指定头文件的查找路径,-L是指定库文件的查找路径,同时还要链库-lcurl,编译后的执行文件在执行的时候出现以下图中错误:因为在程序执行的时候,默认去/usr/lib去找库,然而没有找到,所以我们要设置动态库的环境遍变量:使用指令:export LD_LIBRARY_PATH=库的路径,这种方法临时有效,永久生效的环境变量设置,编辑/etc/profile即可。也可以修改工作目录下的.bashrc 文件。

可以看到/tmp/get.html这个文件夹里面有从百度网页获取的html代码: 

libcurl库函数介绍:

  • curl_global_init(long flags)函数:

功能:初始化libcurl
这个函数只能用一次。(其实在调用curl_global_cleanup 函数后仍然可再用) ,如果这个函数在curl_easy_init函数调用时还没调用,它将由libcurl库自动调用,所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。

注意:虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。

参数:flags
CURL_GLOBAL_ALL                      //初始化所有的可能的调用。
CURL_GLOBAL_SSL                      //初始化支持 安全套接字层。
CURL_GLOBAL_WIN32                  //初始化win32套接字库。
CURL_GLOBAL_NOTHING            //没有额外的初始化。

  • void curl_global_cleanup(void)函数:

结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。注意:虽然libcurl是线程安全的,但curl_global_cleanup是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。

  • char * curl_version( )函数: 打印当前libcurl库的版本。

  • CURL * curl_easy_init( )函数: curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样). 相应的在调用结束时要用url_easy_cleanup函数清理.一般curl_easy_init意味着一个会话的开始. 它会返回一个easy_handle(CURL*对象), 一般都用在easy系列的函数中.
     
  • void curl_easy_cleanup(CURL * handle)函数: 这个调用用来结束一个会话.与curl_easy_init配合着用. 参数:CURL类型的指针.
  • CURLcode curl_easy_perform(CURL * handle)函数: 在初始化CURL类型的指针以及curl_easy_setopt完成后调用. 就像字面的意思所说perform就像是个舞台.让我们设置的option 运作起来.参数:CURL类型的指针。
  • 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手册.

curl_easy_setopt函数部分选项介绍:

主要介绍curl_easy_setopt中跟http相关的参数。该函数是curl中非常重要的函数,curl所有设置都是在该函数中完成的,该函数的设置选项众多,这里阐述的只是部分常见选项。

CURLOPT_URL 设置访问URL

比如:curl_easy_setopt(curl,CURLOPT_URL,"http://www.baidu.com")

CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
回调函数原型为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream); 函数将在libcurl接收到数据后被调用,因此函数多做数据保存的功能,如处理下载文件。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源。如果你没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出。你也可以通过 CURLOPT_WRITEDATA属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。

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

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

CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
跟数据传输进度相关的参数。CURLOPT_PROGRESSFUNCTION 指定的函数正常情况下每秒被libcurl调用一次,为了使CURLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须被设置为false,CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的第一个参数, -

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

CURLOPT_FOLLOWLOCATION,设置重定位URL
 

curl_easy_perform 函数说明(error 状态码):
该函数是完成curl_easy_setopt指定的所有选项,介绍curl_easy_perform的返回值。返回0意味一切ok,非0代表错误发生。主要错误码说明:

CURLE_OK 任务完成一切都好
CURLE_UNSUPPORTED_PROTOCOL 不支持的协议,由URL的头部指定
CURLE_COULDNT_CONNECT 不能连接到remote 主机或者代理
CURLE_REMOTE_ACCESS_DENIED 访问被拒绝
CURLE_HTTP_RETURNED_ERROR Http返回错误
CURLE_READ_ERROR 读本地文件错误
要获取详细的错误描述字符串,可以通过const char *curl_easy_strerror(CURLcode errornum ) 这个函数取得。

参考文章:http协议之libcurl实现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

◣星河◢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值