2、http网络编程——libcurl的使用
1. libcurl介绍
libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。
官网 http://curl.haxx.se/
在基于LibCurl的程序里,主要采用callback function (回调函数)的形式完成传输任务,用户在启动传输前设置好各类参数和回调函数,当满足条件时libcurl将调用用户的回调函数实现特定功能。
利用libcurl完成传输任务的基本流程:
- 调用curl_global_init()初始化libcurl
- 调用curl_easy_init()函数得到 easy interface型指针
- 调用curl_easy_setopt()设置传输选项
- 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务
- 调用curl_easy_perform()函数完成传输任务
- 调用curl_easy_cleanup()释放内存
2. 函数介绍
curl_global_init()
函数原型:
CURLcode curl_global_init(long flags);
函数功能:
初始化libcurl
函数参数:
flags:
CURL_GLOBAL_ALL //初始化所有可能的调用。
CURL_GLOBAL_SSL //初始化支持安全套接字层。
CURL_GLOBAL_WIN32 //初始化win32套接字库。
CURL_GLOBAL_NOTHING //没有额外的初始化。
函数返回值:
如果此函数返回非零,则有问题,不能使用其他curl函数。
curl_global_cleanup
函数原型:
void curl_global_cleanup(void);
函数功能:
在结束libcurl使用的时候,用来对curl_global_init做的工作清理
函数参数:
无
函数返回值:
无
curl_easy_init( )
函数原型:
CURL *curl_easy_init( );
函数功能:
初始化一个CURL的指针
函数参数:
无
函数返回值:
如果此函数返回NULL,则会出现问题,您不能使用其他curl函数。
使用举例
CURL *curl = curl_easy_init();
if(curl) {CURLcode res;curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");res = curl_easy_perform(curl);curl_easy_cleanup(curl);
}
curl_easy_cleanup
函数原型:
void curl_easy_cleanup(CURL *handle)
函数功能:
结束一个CURL *handle
函数参数:
CURL类型的指针,curl_easy_init()创建的
函数返回值:
无
curl_easy_perform
函数原型:
CURLcode curl_easy_perform(CURL *handle)
函数功能:
在初始化CURL类型的指针以及curl_easy_setopt完成后调用,就像字面的意思所说perform就像是个舞台.让我们设置的option 运作起来.
函数参数:
CURL类型的指针,curl_easy_init()创建的
函数返回值:
CURLE_OK(0)表示一切正常,非零表示在定义<curl/curl.h>时发生错误-请参阅libcurl errors
使用举例
CURL *curl = curl_easy_init();
if(curl) {CURLcode res;curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");res = curl_easy_perform(curl);curl_easy_cleanup(curl);
}
curl_easy_setopt
这是最重要的函数,几乎所有的curl 程序都要频繁的使用它。进行数据传输前必须告诉libcurl如何工作,使用这个函数指定工作方式
函数原型:
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
函数功能:
告诉curl库,程序将有如何的行为.
函数参数:
最重要的参数是option,它决定具体的操作是什么,在下面进行介绍
函数返回值:
CURLE_OK(零)表示选项设置正确,非零表示定义<curl/curl.h>时发生错误
curl_easy_getinfo
函数原型:
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );
函数功能:
从curl 句柄提取信息
函数参数:
info:以下信息可被提取
CURLINFO_RESPONSE_CODE——get the last response code
其余见:https://curl.haxx.se/libcurl/c/curl_easy_getinfo.html
函数返回值:
curl_slist_append
函数原型:
struct curl_slist *curl_slist_append(struct curl_slist *list, const char * string);
函数功能:
add a string to an slist
3. CURL option部分介绍
此处介绍的是我用到的一些,其他的查看:
https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
CURLOPT_HTTPGET
作用:ask for an HTTP GET request,如果支持HTTP,则返回CURLE_OK;如果不支持,则返回CURLE_UNKNOWN_选项。
curl = curl_easy_init();
if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");/* use a GET to fetch this */curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);/* Perform the request */curl_easy_perform(curl);
}
CURLOPT_POST
request an HTTP POST
CURLOPT_URL
作用:提供要在请求中使用的URL,这个 URL 是一个以 ‘\0’ 结尾的字符串或参数指针。如果 URL 参数不写上协议头(如 “http://” 或者 "ftp:// 等等 ),那么函数会自己进行猜解所给的主机上用的是哪一种服务协议。
CURLOPT_TIMEOUT
作用:设置允许请求的最长时间
CURLOPT_USERAGENT
设置HTTP的 user-agent头,要求传递一个以 ‘\0’ 结尾的字符串指针,这个字符串用来在向服务器请求时发送 HTTP 头部中的 User-Agent 信息,有些服务器是需要检测这个信息的,如果没有设置 User-Agent,那么服务器拒绝请求。设置后,可以骗过服务器对此的检查。
CURL *curl = curl_easy_init();
if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");curl_easy_setopt(curl, CURLOPT_USERAGENT, "Dark Secret Ninja/1.0");curl_easy_perform(curl);
}
== CURLOPT_WRITEFUNCTION==
设置用于写入接收到的数据的回调,回调函数函数将在libcurl接收到数据后被调用。
原型:
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEFUNCTION, write_callback);
在启动会话时,一旦检测到有需要接收的数据时,回调函数被调用。ptr 所指向的数据大小由 size 和 nmemb 的乘积获得。函数最后需要返回接收数据的大小。如果不使用该函数,那么接收到的数据会直接打印到终端;使用该函数,那么接收到的数据保存在 ptr 所执向的区域,可以利用此来保存接收下来的数据。
使用:
struct memory {char *response;size_t size;};static size_t cb(void *data, size_t size, size_t nmemb, void *userp){size_t realsize = size * nmemb;struct memory *mem = (struct memory *)userp;char *ptr = realloc(mem->response, mem->size + realsize + 1);if(ptr == NULL)return 0; /* out of memory! */mem->response = ptr;memcpy(&(mem->response[mem->size]), data, realsize);mem->size += realsize;mem->response[mem->size] = 0;return realsize;}struct memory chunk;/* send all data to this function */curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, cb);/* we pass our 'chunk' struct to the callback function */curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
CURLOPT_WRITEDATA
传递给写入回调的自定义指针
CURLOPT_HTTPHEADER
设置自定义HTTP头
CURL *curl = curl_easy_init();struct curl_slist *list = NULL;if(curl) {curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");list = curl_slist_append(list, "Shoesize: 10");list = curl_slist_append(list, "Accept:");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);curl_easy_perform(curl);curl_slist_free_all(list); /* free the list again */
}
CURLOPT_POSTFIELDS
指定要发布到服务器的数据
CURL *curl = curl_easy_init();
if(curl) {const char *data = "data to send";curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");/* size of the POST data */curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L);/* pass in a pointer to the data - libcurl will not copy */curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);curl_easy_perform(curl);
}
CURLOPT_POSTFIELDSIZE
指定要发布到服务器的数据的大小
CURLOPT_NOSIGNAL
跳过所有信号处理
CURLOPT_FORBID_REUSE
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_FORBID_REUSE, long close);
使用后立即关闭连接
将close设置为1,使libcurl在完成传输时显式关闭连接。通常,libcurl会在完成一次传输时保持所有连接都处于活动状态,以防后续传输可以重用它们。
设置为0以使libcurl保持连接打开,以便以后可以重用(默认行为)。
CURLOPT_ERRORBUFFER
set error buffer for error messages
curl = curl_easy_init();
if(curl) {CURLcode res;char errbuf[CURL_ERROR_SIZE];curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");/* provide a buffer to store errors in */curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);/* set the error buffer as empty before performing a request */errbuf[0] = 0;/* perform the request */res = curl_easy_perform(curl);/* if the request did not complete correctly, show the errorinformation. if no detailed error information was written to errbufshow the more generic information from curl_easy_strerror instead.*/if(res != CURLE_OK) {size_t len = strlen(errbuf);fprintf(stderr, "\nlibcurl: (%d) ", res);if(len)fprintf(stderr, "%s%s", errbuf,((errbuf[len - 1] != '\n') ? "\n" : ""));elsefprintf(stderr, "%s\n", curl_easy_strerror(res));}
}
CURLOPT_SOCKOPTDATA
传递到sockopt回调的自定义指针
static int sockopt_callback(void *clientp, curl_socket_t curlfd,curlsocktype purpose)
{int val = *(int *)clientp;setsockopt(curldfd, SOL_SOCKET, SO_RCVBUF, (const char *)&val, sizeof(val));return CURL_SOCKOPT_OK;
}curl = curl_easy_init();
if(curl) {int recvbuffersize = 256 * 1024;curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");/* call this function to set options for the socket */curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, &recvbuffersize);res = curl_easy_perform(curl);curl_easy_cleanup(curl);
}
CURLOPT_SOCKOPTFUNCTION
set callback for setting socket options
/* make libcurl use the already established socket 'sockfd' */static curl_socket_t opensocket(void *clientp,curlsocktype purpose,struct curl_sockaddr *address)
{curl_socket_t sockfd;sockfd = *(curl_socket_t *)clientp;/* the actual externally set socket is passed in via the OPENSOCKETDATAoption */return sockfd;
}static int sockopt_callback(void *clientp, curl_socket_t curlfd,curlsocktype purpose)
{/* This return code was added in libcurl 7.21.5 */return CURL_SOCKOPT_ALREADY_CONNECTED;
}curl = curl_easy_init();
if(curl) {/* libcurl will internally think that you connect to the host* and port that you specify in the URL option. */curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");/* call this function to get a socket */curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);/* call this function to set options for the socket */curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);res = curl_easy_perform(curl);curl_easy_cleanup(curl);
2、http网络编程——libcurl的使用相关推荐
- 网络编程知识预备(5) ——libcurl库简介及其编程访问百度首页
本文为学习笔记,整合课程内容以及下列文章: 其中,libcurl函数库常用字段解读部分: 参考博文:原文地址 作者:冬冬他哥哥 目录 Libcurl库简介 Libcurl等三方库的通用编译方法 三方库 ...
- 从零开始的C++网络编程
导语:本文主要介绍如何从零开始搭建简单的C++客户端/服务器,并进行简单的讲解和基础的压力测试演示.该文章相对比较入门,主要面向了解计算机网络但未接触过网络编程的同学. 本文主要分为四个部分: 搭建C ...
- 网络编程知识预备(4) ——了解应用层的HTTP协议与HTTPS协议
参考:简单了解HTTP协议与HTTPS协议 作者:丶PURSUING 发布时间: 2021-03-15 10:55:13 网址:https://blog.csdn.net/weixin_4474282 ...
- 网络编程知识预备(3) ——SOCKET、TCP、HTTP之间的区别与联系
参考:SOCKET,TCP,HTTP之间的区别与联系 作者:丶PURSUING 发布时间: 2021-03-19 11:54:01 网址:https://blog.csdn.net/weixin_44 ...
- 网络编程知识预备(1) ——了解OSI网络模型
参考:简单了解OSI网络模型 作者:丶PURSUING 发布时间: 2021-03-18 20:07:09 网址:https://blog.csdn.net/weixin_44742824/artic ...
- 优秀的开源项目C_适合提高C/C++、网络编程能力的开源项目!不要错过,赶紧收藏...
我们学习每一个编程语言都是有一个项目实战的过程,而对于开发类的编程语言,除了适当的做项目程序外,学习了解其他的开源项目更是一个关键,就比如我们的C/C++编程语言的学习. 前阵子有一个小伙伴就问到我, ...
- VC驿站《VC++网络编程班》开课啦!
原文链接:http://www.cctry.com/thread-240361-1-1.html 〓课程声明〓 VC驿站的各位网友大家好,非常感谢大家的支持.应广大网友要求,VC驿站特推出<VC ...
- 网络编程知识预备(2) —— 三次握手与四次挥手、半连接状态、2MSL
参考:网络编程知识预备(2) --三次握手与四次挥手.流量控制(滑动窗口).拥塞控制.半连接状态.2MSL_行稳方能走远的博客-CSDN博客 目录 一.三次握手 什么是三次握手? 三次握手图解 三次握 ...
- C++网络编程方面的开源项目
Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力. ...
- Linux网络编程--进程间通信(一)
进程间通信简介(摘自<Linux网络编程>p85) AT&T 在 UNIX System V 中引入了几种新的进程通讯方式,即消息队列( MessageQueues),信号量( s ...
最新文章
- java facets_Java UIComponent.getFacets方法代码示例
- 现金流为王!中小企业如何“疫”境求生?
- Android——SQLite实现面向对象CRUD
- 英特尔QSV技术在FFmpeg中的实现与使用
- 2011年度中国地区网络安全威胁大事记
- android蓝牙传输的是字符吗,Android蓝牙接收到的串行数据乱码
- 前端页面-不可编辑控制
- 阿里发布的规约插件,细节都在这里
- Codeforces Round #257 (Div. 2) C. Jzzhu and Chocolate
- linux 文件查找
- 如何将swf文件转换成pdf
- ListView 优化之 ViewHolder 复用机制
- 启动docker容器时报iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport错误
- 基于51单片机的LED彩灯控制器设计
- debian常用指令
- HarmonyOS第三方组件——鸿蒙图片裁剪组件ohos-Image-Cropper
- VC浏览器相关的学习(五)(在BHO中建立对话框)--解决CreateDialog的1813错误
- (ARM)移动处理器与移动互联网终端发展
- 大数据培训需要有基础吗
- Matlab实现 把.tdms文件转换成.mat文件,并读取分割成等长信号数据集
热门文章
- 原有Android/IOS项目集成flutter功能
- CAD中 OLE不能旋转_【设计图文】大空间旋转喷头零件的数控加工工艺设计、编程与加工(有全套cad图+程序+中英文翻译)...
- 第三天:完善数据层(controller)真正对接数据库Mysql
- C#封装DLL类库,调用类库
- C#校验身份证(15位、18位)
- Consul添加配置详解
- ELK logstash的grok 自定义正则匹配日志
- html设置表格边框样式
- Yii Framework2.0开发教程(6)数据库mysql--ActiveRecord
- 升级CentOS到最新版本