当前位置:   article > 正文

第三方库介绍——libcurl库

libcurl库

科普:

  • cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。
  • cURL支持的通信协议有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。
  • curl还支持SSL认证、HTTP POST、HTTP PUT、FTP上传, HTTP form based upload、proxies、HTTP/2、cookies、用户名+密码认证(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos)、file transfer resume、proxy tunneling。

一、Libcurl库简介

  • libcurl库:在linux下用c语言做HTTP的编程,可以用于做跨平台网络协议相关的开发
  • libcurl是一个跨平台的网络协议库,支持http, https, ftp等协议,libcurl同样支持:

(1)HTTPS证书授权
(2)HTTP POST, HTTP PUT, FTP 上传
(3)HTTP基本表单上传,代理,cookies,和用户认证

libcur库下载地址:下载curl-7.71.1.tar.bz2
在这里插入图片描述
将下载好的压缩包发送到ubuntu

二、Libcurl等三方库的通用编译方法

解压下载的库

tar xvf curl-7.71.1.tar.bz2
  • 1

进入文件夹

cd curl-7.71.1
  • 1

(1)三方库使用前通读方法

关于第三方库的使用手册可以阅读README文件,或者进入docs目录下阅读INSTALL.md文件

(2)库的配置、编译、安装

阅读INSTALL.md文件可知在unix环境下的安装步骤和安装时候指定的配置

在这里插入图片描述
安装步骤:

在这里插入图片描述

配置参数查看:

./configure --help
  • 1

通过配置更改安装位置:

在这里插入图片描述

代码案例:$ 获取当前路径,编译的时候会自动生成_install文件夹,并且把编译生成的东西全部放入这个文件夹。

./configure --prefix=$PWD/_install
  • 1

通过配置完成交叉编译

在这里插入图片描述
代码案例:编译后在树莓派上用,此处用的是树莓派的交叉编译工具链而不是gcc(树莓派没有cmake则需要在宿主机上进行交叉编译)

./configure --prefix=$PWD/_install --host=arm-linux
  • 1

编译、安装

make
make install //将编译后的文件拷贝到根目录的指定文件夹下
  • 1
  • 2

安装完成后在的当前路径下会有_install文件夹

此时头文件在/include/curl下
在这里插入图片描述
链接库的位置在/lib
在这里插入图片描述

三、测试代码

功能:调用libcurl编程访问百度主页
注意: C++里有专门的bool类型,用来表示真或假。但是在C语言里没有这样的类型,为了修改方便直接选择替换bool数据类型以及true和false变量( 类似于bool,true,faluse,这是C99标准才会支持)
测试代码来源:http协议之libcurl

(1)代码:

#include <stdio.h>
#include <curl/curl.h>
 
typedef unsigned int bool;//数据类型别名用typedef  有分号
#define true 1            //宏定义(替换)用define         无冒号
#define false 0
 
bool getUrl(char *filename)//GET请求
{
        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>指向的文件,
                //即为filename文件,而主函数传入的参数是 /tmp/get.html,即为真正保存在get.html文件中
                
                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)//POST请求
{
        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");
}
 
  • 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
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

(2)编译和运行

gcc demo1.c -I ./curl-7.71.1/_install/include/ -L ./curl-7.71.1/_install/lib/ -lcurl
  • 1

注意:

  • 编译时链接库、头文件路径、库的名称
  • 若运行的时候报错
    在这里插入图片描述 运行需添加动态库为环境变量(不报错则不需要,可能因为ubuntu版本不一样)
    • export LD_LIBRARY_PATH=./curl-7.71.1/_install/lib/
    • export | grep LD_LIB 可以看到添加的路径
    • 需要添加环境变量的原因可能是库之间的依赖问题
      在这里插入图片描述

(3)查看获取网页源代码

  • 成功运行后,可以看到vi /tmp/get.html中已经有了百度官网的代码。 而 vi /tmp/port.html 里面不会有东西,因为账号密码没有填写正确

四、libcurl函数库常用字段解读

参考博文:http协议之libcurl

(1)curl_global_init():初始化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         //没有额外的初始化。
  • 1
  • 2
  • 3
  • 4

(2)curl_easy_init():拿到句柄

  • 用来初始化一个CURL的指针(有些像返回FILE类型的指针一样)。相应的在调用结束时要用curl_easy_cleanup函数清理。

  • 一般curl_easy_init意味着一个会话的开始. 它会返回一个easy_handle(CURL*对象), 一般都用在easy系列的函数中。

  • 后续所有的操作都是对这个指针进行设置,把这种类型的指针就叫做句柄

(3)curl_easy_setopt(CURL *handle, CURLoption option, parameter):设置传输选项

  • 这个函数很重要,几乎所有的curl 程序都要频繁的使用它。它告诉curl库,程序将有如何的行为,比如要查看一个网页的html代码等。(这个函数有些像ioctl函数)
  • 根据设置的传输选项,实现回调函数以完成用户特定任务(设置与操作句柄)

参数:

1)CURL类型的指针
(2)CURLoption类型的选项.(都在curl.h库里有定义,man 也可以查看到)3)parameter 既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量,取决于第二个参数。
  • 1
  • 2
  • 3

第二个参数CURLoption常用的宏:

  • (1)CURLOPT_URL:

    • 设置访问URL(访问的网址)
  • (2)CURLOPT_POSTFIELDS

    • 在post请求中:以 & 拼接字符串的形式把参数链接起来
    • 例如:curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86");
  • (3)CURLOPT_WRITEFUNCTION

    • 回调函数:网页有数据请求回来的时候,如何去处理这些数据。函数多做数据保存的功能,如处理下载文件。
    • 设置的回调函数格式要求为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
      • 第一个参数:无类型指针(看做字符串)指向的就是数据,可以用函数strncpy或strcpy接收到本地
      • 第二个参数:回调函数的名称
  • (4)CURLOPT_WRITEDATA

    • CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源。
    • libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出
    • 可以通过 CURLOPT_WRITEDATA 属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。
      • 前提是已经打开一个文件流:fp = fopen(filename, "w")
      • 第三个参数传递文件指针,表示请求回来的所有数据都放到文件

(4)curl_easy_perform():执行任务

  • 在初始化CURL类型的指针以及curl_easy_setopt完成后调用.,就像字面的意思所说 perform 就像是个舞台,让我们设置的option 运作起来。

(5)curl_easy_cleanup():释放内存

  • 结束libcurl使用的时候,用来对 curl_global_init 做的工作清理。类似于close的函数。
  • 参数是curl句柄
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/744060
推荐阅读
相关标签
  

闽ICP备14008679号