电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
linux中级——libcurl库访问百度
分 享
扫描二维码分享
linux中级——libcurl库访问百度
linux
curl
一口Linux
关注
发布时间: 2022-06-27
丨
阅读: 1092
# libcurl简介: libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。[libcurl的官网](https://curl.se/) 、[库下载](https://github.com/curl/curl/releases/tag/curl-7_71_1)。这种库使用的时候就像使用wiringPi库一样,编写完代码需要链接这个库,所以要先下载这个库。 ## libcurl等第三方库的通用编译方法: - 首先进入libcurl库得下载界面,点击下载libcurl库 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7c6e36f89dde4a1d91194b729e484cb3.png) - 下载完成后通过共享文件夹或者FileZill或者直接拖拽将压缩包移动到虚拟机。我这里将压缩包拖拽至虚拟机的共享文件夹,然后使用指令:`cp /mnt/hgfs/sharefile/curl-7.71.1.tar.bz2 .`将压缩包拷贝到我新建的httpHandler这个文件夹里面,然后使用指令:`tar vxf curl-7.71.1.tar.bz2`解压这个文件夹,解压后进入文件夹,如下图所示(之后用到的开源的库基本都是这样的,内容形式差不多): ![在这里插入图片描述](https://img-blog.csdnimg.cn/8af4b1c7ea6f48f6bf2adbd7930aa69b.png) - 那么如何使用这种开源的压缩包呢?这个文件夹下面有一个README文件夹,里面有对库的一些说明,如下图所示,由下图可知,我们使用libcurl库时可以查看curl.1手册或者MANUAL document这个手册 ![在这里插入图片描述](https://img-blog.csdnimg.cn/44ad2b4294c249bb8a0801c30e006ad0.png) - 这里我用有道翻译将这些英文进行了简单地翻译: > 自述:Curl是一个命令行工具,用于传输由URL(网址)指定的数据语法。通过阅读curl了解如何使用curl。手册页或手册文档。通过阅读install了解如何安装Curl文档。Libcurl是curl用来完成其工作的库。它很容易可被您的软件使用。阅读libcurl。3手册页学习如何!你可以在FAQ文档中找到最常见问题的答案。研究copy文件中的分发条款和类似条款。如果你分配Curl二进制文件或其他涉及libcurl的二进制文件,您可能会喜欢LICENSE-MIXING文档。所有这些文档以及更多文档都可以在docs/目录中找到。联系:如果您有问题、疑问、想法或建议,请与我们联系通过邮寄到一个合适的邮寄名单。参见http//curl.haxx.se/mail/该项目的所有贡献者都列在THANKS文档中。网站:访问curl网站获取最新消息和下载:https://curl.haxx.se/,GIT:要从GIT服务器上下载最新的源代码,请这样做:git克隆https://github.com/curl/curl.git,(您将创建一个名为curl的目录,并填充源代码)。安全问题:通过我们的HackerOne页面报告可疑的安全问题,而不是在公共场合!https://hackerone.com/curl请注意:Curl包含的源代码是版权所有©1998, 1999。终于Tekniska Hogskolan。在此附上此通知是为了遵守分布条件。 - 通过阅读`README`我们并没有找到如何使用这个库,然后进入到`docs`这个文件夹,这个文件夹是对`RADME`的一个补充,在这个文件夹下面我们会看到`README`里面提到的`curl1.1`这个API相关的手册,还有`INSTALL`(**==这个一定要看,有时候他会和`README`都放在解压后的文件夹里面,有时候会放在`docs`里面==**)。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2e6a6f4a35a84139b5ea58440703704e.png) - 打开`INSTALL`后看到 提示说如何编译(compile)这个库请看`INSTALL.md`这个文件,打开这个文件后,里面有介绍如何安装编译后的`libcurl库`,然后下面可以看到在UNIX环境下面如何进行安装 如下图所示,**`./config`就是配置的一个东西**,就是将库安装到哪里,**若后面不跟任何的参数,就是默认安装(可能安装在`/usr/lib`或者`/usr/include`下面)。** ==`make`就是编译的意思,`make install`就是将编译后的东西拷贝到根目录的相关文件夹下面。如果默认安装的话可能需要`root权限`== **因为:默认可能安装在/usr/lib或者/usr/include下面,而访问这两个文件夹需要root权限。** ![在这里插入图片描述](https://img-blog.csdnimg.cn/704223ff7a7b414484b3887a39faf2d7.png) - 当然一般不安装在默认的路径下面,可以通过下图方式指定安装路径 ![在这里插入图片描述](https://img-blog.csdnimg.cn/ac52b5d362ab47dfbfc0d947812ff5fc.png) ![在这里插入图片描述](https://img-blog.csdnimg.cn/e187e26fe94c4d09b1613ff980a48f5d.png) - 通过指令:`./configure --help`可以查看`configure`都支持哪些功能参数,其中下面的`HOST`这个指令可以指定交叉编译的编译器(若不指定交叉编译工具默认使用`gcc`编译工具)。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/3bab6aca6386456e9c7c0207cf0d7b5c.png) - 通过以下指令:`./configure --prefix=$PWD/_install`进行指定位置的安装,安装的时候会生成一个`_install`文件夹,库将会被安装到这个文件夹下面,安装过程中没有出现任何error表示安装成功,然后使用指令:`make`进行编译,然后使用使用指令:`make install`进行拷贝,然后会发现当前文件夹下面生成了一个`_install`文件夹,然后进入到该文件夹,如下图所示: ![在这里插入图片描述](https://img-blog.csdnimg.cn/c8e5f0cc7510400ab375740c46bbd754.png) ## 调用libcurl库访问百度 **调用libcurl库访问百度主页并将数据保存到文件中:** 程序代码: ```c #include
#include
#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; } } bool postUrl(char *filename) { 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"); } ``` > 大概解读代码: > 要用一个是`getUrl`,一个是`postUrl`,用**get**跟**post**两种方法来请求的一个网页。 > `getUrl`,我们来看一下,是自己封装的这个函数,`fopen`这个函数去打开了一个文件,放在**fp**这个流里面。然后`curl_easy_init`去做初始化,去初始化我们的curl引擎,**初始化成功以后`curl_easy_setopt`去设置curl相关的项,** 包括我们要访问的IP地址等等,还有一个`CURLOPT_WRITEDATA`。访问成功数据返回以后呢会把数据流导入到这个`filename`这个文件里面,那`filename`文件是哪里呢?在`/tmp/get.html`。这文件如果没有的话,他这边`fp = fopen(filename, "w")`应该会创建啊,[去回顾一下文件相关的操作](https://blog.csdn.net/weixin_44278698/article/details/123581754)。然后将返回的 **`html主体数据`输出到`fp`指向的文件** ,**`百度的访问的所有结果往文件里面去写`**,然后`curl_easy_perform`执行就是在访问百度,如果`res != 0`,这个res不等于零是啥意思呢?我们去回顾一下之前提到的这个进行http请求以后的一个返回值,如果请求成功以后啊,我们去释放这相关的`curl`的这个句柄。并且关闭这个文件,`return true;`访问成功,这个是相关的步骤 - 使用指令: `gcc demo1.c -I ./curl-7.71.1/_install/include/ -L./curl-7.71.1/_install/lib/ -lcurl`进行编译,**-I是指定头文件的查找路径,-L是指定库文件的查找路径,同时还要-l curl**,编译后的执行文件在执行的时候出现以下图中错误: ![在这里插入图片描述](https://img-blog.csdnimg.cn/963b3ae5de67410f99329e3c47efc3b9.png) 因为**在程序执行的时候,默认去/usr/lib去找库**,然而没有找到,所以我们要设置动态库的环境遍变量:使用指令:`export LD_LIBRARY_PATH=库的路径`,这种方法临时有效,永久生效的环境变量设置,编辑`/etc/profile`即可。也可以修改工作目录下的`.bashrc` 文件。 [linux动态库,静态库](https://blog.csdn.net/weixin_44278698/article/details/124150266) 通过以上设置然后再执行程序:可以看到`/tmp/get.html`这个文件夹里面有从百度网页获取的html代码: ![在这里插入图片描述](https://img-blog.csdnimg.cn/21f6dd00364f4af6beda586918921a71.png) # libcurl库函数介绍: ## curl_global_init(long flags)函数: > - **libcurl的使用(其实和socket编程时一样,都需要一定的步骤):** > > 1. 调用curl_global_init()初始化libcurl,(就像初始化套接字) > 2. 调用curl_easy_init()函数得到 easy interface型指针(这个指针用来各种配置) > 3. 调用curl_easy_setopt()设置传输选项(通过调curl_easy_setopt这个函数来对指针进行各种配置,比如:请求的方式) > 4. 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务 > 5. 调用curl_easy_perform()函数进行访问请求 > 6. 调用curl_easy_cleanup()释放内存 函数简介 > `CURLcode curl_global_init(long flags)` > 功能:**初始化libcurl** 这个函数只能用一次。(其实在调用curl_global_cleanup 函数后仍然可再用) > 如果这个函数在**curl_easy_init函数调用时还没调用**,**它将由libcurl库自动调用** > 所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。 > > 注意:虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的, 所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。 ```c 参数: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_setopt(CURL * handle, CURLoption option,parameter)`函数:** > - **这个函数最重要了.几乎所有的curl 程序都要频繁的使用它.它告诉curl库.程序将有如何的行为. 比如要查看一个网页的html代码等.(这个函数有些像ioctl函数)** > **** > **参数:** > 1. CURL类型的指针 > 2. 各种CURLoption类型的选项.(都在curl.h库里有定义,man 也可以查看到) > 3. parameter 这个参数 既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量.它用什么这取决于第二个参数. CURLoption > 这个参数的取值很多.具体的可以查看man手册. - **`CURLcode curl_easy_perform(CURL *handle)`函数**; 在初始化CURL类型的指针 以及curl_easy_setopt完成后调用. 就像字面的意思所说perform就像是个舞台.让我们设置的 option 运作起来.参数: CURL类型的指针.
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
一口Linux
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交