由于这两天弄一个http下载文件的功能,使用libcurl库,第一次使用libcurl库,也是边查资料边改代码,因此想顺便记录一下,供以后自己查看
注意:本文是参考其他博主文章学习总结
原博主链接: https://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html
libcurl 作为是一个多协议的便于客户端使用的URL传输库,该库基于C语言实现,提供C语言的API接口.
libcurl 是一个高移植性的库,能在绝大多数系统上运行.
支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S,RTMP,RTSP,SCP,SFTP,SMTP,SMTPS,Telnet,TFTP这些协议。
同时支持使用SSL证书的安全文件传输: HTTP POST, HTTP PUT,FTP上传, 基于HTTP形式的上传、代理、Cookies、用户加密码的认证等多种应用场景。
1. 调用 curl_global_init() 初始化libcurl库
2. 调用 curl_easy_init() 函数得到 easy interface型指针
4. 根据 curl_easy_setopt() 设置的传输选项,实现回调函数以完成用户特定任务
5. 调用 curl_easy_perform() 函数完成传输任务
6. 调用 curl_easy_cleanup() 释放内存
7. 调用 curl_global_cleanup() 释放libcurl
1. curl_global_init 函数
函数: CURLcode curl_global_init(long flags);
函数功能: 主要用于libcurl库的初始化
函数参数: falgs
CURL_GLOBAL_ALL //初始化所有的可能的调用。
CURL_GLOBAL_SSL //初始化支持 安全套接字层。
CURL_GLOBAL_WIN32 //初始化win32套接字库。
CURL_GLOBAL_NOTHING //没有额外的初始化。
CURL_GLOBAL_DEFAULT //将初始化 win32 和 ssl,相当于CURL_GLOBAL_ALL掩码功能
CURL_GLOBAL_ACK_EINTR //7.69.0版本后没有任何意义,但其行为是默认值。版本之前设置此标志时,curl将在连接或等待数据时确认EINTR条件。否则,curl等待直到完全超时结束。
注: 这个函数只能用一次(其实在调用curl_global_cleanup 函数后仍然可再用)。
2. curl_global_cleanup 函数
函数: void curl_global_cleanup(void);
函数功能: 主要用于释放libcurl的初始化
3. curl_version 函数
函数: char *curl_version( );
函数功能: 主要用于获取libcurl的版本
4. curl_easy_init 函数
函数: CURL *curl_easy_init( );
函数功能: 主要用来启动libcurl easy会话,此函数必须是要调用的第一个函数,它返回一个CURL easy句柄
函数例子:
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);
}
5. curl_easy_cleanup 函数
函数: void curl_easy_cleanup(CURL *handle);
函数功能: 主要用来释放 curl_easy_init 函数初始化获取到的CURL easy句柄
6. curl_easy_setopt 函数
函数: CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
函数功能: 主要用来设置选项,应用程序更改libcurl行为,所有选项都设置为一个选项后跟一个参数, 在每次函数调用中只能设置一个选项,使用此函数调用设置的选项对于使用此句柄执行的所有即将进行的传输都有效, 在传输之间重置,因此如果希望后续传输具有不同的选项,则必须在传输之间更改它们
参数:
1. CURL easy句柄
2. 各种CURLoption类型的选项
3. parameter 这个参数 既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量.它用什么这取决于第二个参数.
CURLoption option 参数值如下:
行为选项:
CURLOPT_VERBOSE //显示详细信息
CURLOPT_HEADER //在正文输出中包含标题
CURLOPT_NOPROGRESS //关闭进度表
CURLOPT_NOSIGNAL //不要安装信号处理程序
CURLOPT_WILDCARDMATCH //根据文件名模式传输多个文件
回调选项:
CURLOPT_WRITEFUNCTION //用于写入数据的回调
CURLOPT_WRITEDATA //传递给写回调的数据指针
CURLOPT_READFUNCTION //读取数据回调
CURLOPT_READDATA //传递给读取回调的数据指针
CURLOPT_IOCTLFUNCTION //I/O操作回调
CURLOPT_IOCTLDATA //传递给I/O回调的数据指针
CURLOPT_SEEKFUNCTION //查找操作的回调
CURLOPT_SEEKDATA //传递给seek回调的数据指针
CURLOPT_SOCKOPTFUNCTION //sockopt操作回调
CURLOPT_SOCKOPTDATA //传递给sockopt回调的数据指针
CURLOPT_OPENSOCKETFUNCTION //用于创建套接字的回调
CURLOPT_OPENSOCKETDATA //传递给打开套接字回调的数据指针
CURLOPT_CLOSESOCKETFUNCTION //用于关闭套接字的回调
CURLOPT_CLOSESOCKETDATA //传递给关闭套接字回调的数据指针
CURLOPT_PROGRESSFUNCTION //进度表的过时回调
CURLOPT_PROGRESSDATA //传递给进度表回调的数据指针
CURLOPT_XFERINFOFUNCTION //回调进度表
CURLOPT_XFERINFODATA //传递给进度表回调的数据指针
CURLOPT_HEADERFUNCTION //用于写入接收头的回调
CURLOPT_HEADERDATA //传递给头回 调的数据指针
CURLOPT_DEBUGFUNCTION //调试信息的回调
CURLOPT_DEBUGDATA //传递给调试回调的数据指针
CURLOPT_SSL_CTX_FUNCTION //SSL上下文逻辑的回调
CURLOPT_SSL_CTX_DATA //传递给SSL上下文回调的数据指针
CURLOPT_CONV_TO_NETWORK_FUNCTION //代码基础转换的回调
CURLOPT_CONV_FROM_NETWORK_FUNCTION //代码基础转换的回调
CURLOPT_CONV_FROM_UTF8_FUNCTION //代码基转换的回调
CURLOPT_INTERLEAVEFUNCTION //RTSP交错数据的回调
CURLOPT_INTERLEAVEDATA //传递给RTSP交错回调的数据指针
CURLOPT_CHUNK_BGN_FUNCTION //块的通配符下载开始回调
CURLOPT_CHUNK_END_FUNCTION //块的通配符下载结束回调
CURLOPT_CHUNK_DATA //传递给块回调的数据指针
CURLOPT_FNMATCH_FUNCTION //用于通配符匹配的回调
CURLOPT_FNMATCH_DATA //传递给通配符匹配回调的数据指针
CURLOPT_SUPPRESS_CONNECT_HEADERS //禁止用户回调的代理连接响应头
CURLOPT_RESOLVER_START_FUNCTION //在启动新的解析请求之前要调用的回调
CURLOPT_RESOLVER_START_DATA //传递给解析器启动回调的数据指针
错误选项:
CURLOPT_ERRORBUFFER //错误消息缓冲区
CURLOPT_STDERR //标准更换流
CURLOPT_FAILONERROR //HTTP 4xx错误时失败
CURLOPT_KEEP_SENDING_ON_ERROR //持续发送HTTP>=300错误
网络选项:
CURLOPT_URL //URL工作打开
CURLOPT_PATH_AS_IS //禁用路径中的/../和/./
CURLOPT_PROTOCOLS //允许的协议
CURLOPT_REDIR_PROTOCOLS //允许重定向到的协议
CURLOPT_DEFAULT_PROTOCOL //默认协议
CURLOPT_PROXY //要使用的代理
CURLOPT_PRE_PROXY //socks代理
CURLOPT_PROXYPORT //要使用的代理端口
CURLOPT_PROXYTYPE //代理类型
CURLOPT_NOPROXY //从代理使用中筛选出主机
CURLOPT_HTTPPROXYTUNNEL //通过HTTP代理通道
CURLOPT_CONNECT_TO //连接到特定的主机和端口
CURLOPT_SOCKS5_AUTH //Socks5身份验证方法
CURLOPT_SOCKS5_GSSAPI_SERVICE //Socks5 GSSAPI服务名称
CURLOPT_SOCKS5_GSSAPI_NEC //socks5 GSSAPI NEC模式
CURLOPT_PROXY_SERVICE_NAME //代理身份验证服务名称
CURLOPT_HAPROXYPROTOCOL //发送HAProxy代理协议v1头
CURLOPT_SERVICE_NAME //身份验证服务名称
CURLOPT_INTERFACE //将连接本地绑定到此
CURLOPT_LOCALPORT //将连接本地绑定到此端口
CURLOPT_LOCALPORTRANGE //将连接本地绑定到端口范围
CURLOPT_DNS_CACHE_TIMEOUT //DNS缓存超时
CURLOPT_DNS_USE_GLOBAL_CACHE //启用全局DNS缓存
CURLOPT_DOH_URL //使用此DOH服务器进行名称解析
CURLOPT_BUFFERSIZE //询问备用缓冲区大小
CURLOPT_PORT //要连接的端口号
CURLOPT_TCP_FASTOPEN //启用TFO,TCP快速打开
CURLOPT_TCP_NODELAY //禁用Nagle算法
CURLOPT_ADDRESS_SCOPE //本地地址的IPv6作用域
CURLOPT_TCP_KEEPALIVE //启用TCP保持活动状态
CURLOPT_TCP_KEEPIDLE //发送前的空闲时间保持活动
CURLOPT_TCP_KEEPINTVL //保持活动探头之间的间隔
CURLOPT_UNIX_SOCKET_PATH //Unix域套接字的路径
CURLOPT_ABSTRACT_UNIX_SOCKET //抽象Unix域套接字的路径
名称和密码选项(身份验证):
CURLOPT_NETRC //启用.netrc解析
CURLOPT_NETRC_FILE //.netrc文件名
CURLOPT_USERPWD //用户名和密码
CURLOPT_PROXYUSERPWD //代理用户名和密码
CURLOPT_USERNAME //用户名
CURLOPT_PASSWORD //密码
CURLOPT_LOGIN_OPTIONS //登录选项
CURLOPT_PROXYUSERNAME //代理用户名
CURLOPT_PROXYPASSWORD //代理密码
CURLOPT_HTTPAUTH //HTTP服务器身份验证方法
CURLOPT_TLSAUTH_USERNAME //TLS身份验证用户名
CURLOPT_PROXY_TLSAUTH_USERNAME //代理TLS身份验证用户名
CURLOPT_TLSAUTH_PASSWORD //TLS身份验证密码
CURLOPT_PROXY_TLSAUTH_PASSWORD //代理TLS身份验证密码
CURLOPT_TLSAUTH_TYPE //TLS身份验证方法
CURLOPT_PROXY_TLSAUTH_TYPE //代理TLS身份验证方法
CURLOPT_PROXYAUTH //HTTP代理身份验证方法
CURLOPT_SASL_AUTHZID //SASL授权身份(身份扮演者)
CURLOPT_SASL_IR //启用SASL初始响应
CURLOPT_XOAUTH2_BEARER //OAuth2承载令牌
CURLOPT_DISALLOW_USERNAME_IN_URL //不允许在URL中使用用户名
HTTP选项:
CURLOPT_AUTOREFERER //自动设置Referer:header
CURLOPT_ACCEPT_ENCODING //接受编码和自动解压缩数据
CURLOPT_TRANSFER_ENCODING //请求传输编码
CURLOPT_FOLLOWLOCATION //遵循HTTP重定向
CURLOPT_UNRESTRICTED_AUTH //不要将身份验证限制到原始主机
CURLOPT_MAXREDIRS //要遵循的最大重定向数
CURLOPT_POSTREDIR //如何在发布后对重定向进行操作
CURLOPT_PUT //发出HTTP PUT请求
CURLOPT_POST //发出HTTP POST请求
CURLOPT_POSTFIELDS //用这些数据发送一个帖子
CURLOPT_POSTFIELDSIZE //POST数据这么大
CURLOPT_POSTFIELDSIZE_LARGE //POST数据这么大
CURLOPT_COPYPOSTFIELDS //用这些数据发送一个帖子-然后复制它
CURLOPT_HTTPPOST //多部分格式HTTP POST
CURLOPT_REFERER //参考:header
CURLOPT_USERAGENT //用户代理:header
CURLOPT_HTTPHEADER //自定义HTTP头
CURLOPT_HEADEROPT //控制自定义标题
CURLOPT_PROXYHEADER //发送到代理的自定义HTTP头
CURLOPT_HTTP200ALIASES //200的替代版本可以
CURLOPT_COOKIE //要发送的Cookie
CURLOPT_COOKIEFILE //要从中读取cookie的文件
CURLOPT_COOKIEJAR //写入Cookie的文件
CURLOPT_COOKIESESSION //启动新的cookie会话
CURLOPT_COOKIELIST //添加或控制cookies
CURLOPT_ALTSVC //指定Alt Svc:cache文件名
CURLOPT_ALTSVC_CTRL //启用并配置Alt Svc:treatment
CURLOPT_HTTPGET //执行HTTP GET请求
CURLOPT_REQUEST_TARGET //设置请求目标
CURLOPT_HTTP_VERSION //要使用的HTTP版本
CURLOPT_HTTP09_ALLOWED //允许HTTP/0.9响应
CURLOPT_IGNORE_CONTENT_LENGTH //忽略内容长度
CURLOPT_HTTP_CONTENT_DECODING //禁用内容解码
CURLOPT_HTTP_TRANSFER_DECODING //禁用传输解码
CURLOPT_EXPECT_100_TIMEOUT_MS //100超时
CURLOPT_TRAILERFUNCTION //设置用于发送尾部标头的回调
CURLOPT_TRAILERDATA //传递给尾部标头回调的自定义指针
CURLOPT_PIPEWAIT //等待连接到它上面的管道
CURLOPT_STREAM_DEPENDS //这个HTTP/2流依赖于另一个
CURLOPT_STREAM_DEPENDS_E //此HTTP/2流以独占方式依赖于另一个HTTP/2流
CURLOPT_STREAM_WEIGHT //设置此HTTP/2流的权重
SMTP选项:
CURLOPT_MAIL_FROM //发件人的地址
CURLOPT_MAIL_RCPT //收件人的地址
CURLOPT_MAIL_AUTH //身份验证地址
CURLOPT_MAIL_RCPT_ALLLOWFAILS //允许RCPT命令对某些收件人失败
TFTP选项:
CURLOPT_TFTP_BLKSIZE //TFTP块大小
CURLOPT_TFTP_NO_OPTIONS //不发送TFTP选项请求
FTP选项:
CURLOPT_FTPPORT //使用活动FTP
CURLOPT_QUOTE //传输前要运行的命令
CURLOPT_POSTQUOTE //传输后要运行的命令
CURLOPT_PREQUOTE //在传输之前运行的命令
CURLOPT_APPEND //附加到远程文件
CURLOPT_FTP_USE_EPRT //使用REPTR
CURLOPT_FTP_USE_EPSV //使用EPSV
CURLOPT_FTP_USE_PRET //使用PRET
CURLOPT_FTP_CREATE_MISSING_DIRS //在远程服务器上创建缺少的目录
CURLOPT_FTP_RESPONSE_TIMEOUT //FTP响应超时
CURLOPT_FTP_ALTERNATIVE_TO_USER //用户的替代方案
CURLOPT_FTP_SKIP_PASV_IP //忽略PASV响应中的IP地址
CURLOPT_FTPSSLAUTH //控制如何进行TLS
CURLOPT_FTP_SSL_CCC //身份验证后再次返回非TLS
CURLOPT_FTP_ACCOUNT //发送ACCT命令
CURLOPT_FTP_FILEMETHOD //指定如何访问文件
RTSP选项:
CURLOPT_RTSP_REQUEST //RTSP请求
CURLOPT_RTSP_SESSION_ID //RTSP会话id
CURLOPT_RTSP_STREAM_URI //RTSP流URI
CURLOPT_RTSP_TRANSPORT //RTSP传输:header
CURLOPT_RTSP_CLIENT_CSEQ //CSEQ客户编号
CURLOPT_RTSP_SERVER_CSEQ //RTSP服务器->客户端请求的CSEQ号
PROTOCOL选项:
CURLOPT_TRANSFERTEXT //使用文本传输
CURLOPT_PROXY_TRANSFER_MODE //通过代理向URL添加传输模式
CURLOPT_CRLF //转换换行符
CURLOPT_RANGE //范围请求
CURLOPT_RESUME_FROM //继续调职
CURLOPT_RESUME_FROM_LARGE //继续调职
CURLOPT_CURLU //设置URL以使用CURLU*
CURLOPT_CUSTOMREQUEST //自定义请求/方法
CURLOPT_FILETIME //请求文件修改日期和时间
CURLOPT_DIRLISTONLY //仅列出
CURLOPT_NOBODY //不要获取身体内容
CURLOPT_INFILESIZE //要发送的文件大小
CURLOPT_INFILESIZE_LARGE //要发送的文件大小
CURLOPT_UPLOAD //上传数据
CURLOPT_UPLOAD_BUFFERSIZE //设置上载缓冲区大小
CURLOPT_MIMEPOST //发布/发送MIME数据
CURLOPT_MAXFILESIZE //要获取的最大文件大小
CURLOPT_MAXFILESIZE_LARGE //要获取的最大文件大小
CURLOPT_TIMECONDITION //提出有时间条件的请求
CURLOPT_TIMEVALUE //时间条件请求的时间值
CURLOPT_TIMEVALUE_LARGE //时间条件请求的时间值
CONNECTION 选项:
CURLOPT_TIMEOUT //整个请求超时
CURLOPT_TIMEOUT_MS //整个请求的毫秒超时
CURLOPT_LOW_SPEED_LIMIT //低速限制中止传输
CURLOPT_LOW_SPEED_TIME //低于触发低速中止的速度的时间
CURLOPT_MAX_SEND_SPEED_LARGE //把上传速度限制到这个
CURLOPT_MAX_RECV_SPEED_LARGE //将下载速度限制为这个
CURLOPT_MAXCONNECTS //连接池中的最大连接数
CURLOPT_FRESH_CONNECT //使用新连接
CURLOPT_FORBID_REUSE //防止后续连接重复使用此选项
CURLOPT_MAXAGE_CONN //限制重新使用连接的时间
CURLOPT_CONNECTTIMEOUT //连接阶段超时
CURLOPT_CONNECTTIMEOUT_MS //连接阶段的毫秒超时
CURLOPT_IPRESOLVE //要解析为的IP版本
CURLOPT_CONNECT_ONLY //只有连接
CURLOPT_USE_SSL //使用TLS/SSL
CURLOPT_RESOLVE //提供固定/假名称解析
CURLOPT_DNS_INTERFACE //绑定名称解析到此接口
CURLOPT_DNS_LOCAL_IP4 //绑定名称解析到此IP4地址
CURLOPT_DNS_LOCAL_IP6 //绑定名称解析到此IP6地址
CURLOPT_DNS_SERVERS //首选DNS服务器
CURLOPT_DNS_SHUFFLE_ADDRESSES //使用前请重新洗牌地址
CURLOPT_ACCEPTTIMEOUT_MS //等待服务器的连接被接受超时
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS //快乐眼球超时
CURLOPT_UPKEEP_INTERVAL_MS //设置执行连接维护的间隔
SSL and SECURITY 选项:
CURLOPT_SSLCERT //正确的客户
CURLOPT_PROXY_SSLCERT //代理客户端证书
CURLOPT_SSLCERTTYPE //证书类型客户端
CURLOPT_PROXY_SSLCERTTYPE //代理客户端证书类型
CURLOPT_SSLKEY //客户端密钥
CURLOPT_PROXY_SSLKEY //代理客户端密钥
CURLOPT_SSLKEYTYPE //客户端密钥类型
CURLOPT_PROXY_SSLKEYTYPE //代理客户端密钥类型
CURLOPT_KEYPASSWD //客户端密钥密码
CURLOPT_PROXY_KEYPASSWD //代理客户端密钥密码
CURLOPT_SSL_ENABLE_ALPN //启用ALPN
CURLOPT_SSL_ENABLE_NPN //启用NPN
CURLOPT_SSLENGINE //将标识符与SSL引擎一起使用
CURLOPT_SSLENGINE_DEFAULT //默认SSL引擎
CURLOPT_SSL_FALSESTART //启用TLS错误启动
CURLOPT_SSLVERSION //要使用的SSL版本
CURLOPT_PROXY_SSLVERSION //要使用的代理SSL版本
CURLOPT_SSL_VERIFYHOST //验证SSL证书中的主机名
CURLOPT_PROXY_SSL_VERIFYHOST //验证代理SSL证书中的主机名
CURLOPT_SSL_VERIFYPEER //验证SSL证书
CURLOPT_PROXY_SSL_VERIFYPEER //验证代理SSL证书
CURLOPT_SSL_VERIFYSTATUS //验证SSL证书的状态
CURLOPT_CAINFO //CA证书捆绑包
CURLOPT_PROXY_CAINFO //代理CA证书捆绑包
CURLOPT_ISSUERCERT //颁发者证书
CURLOPT_CAPATH //CA证书包的路径
CURLOPT_PROXY_CAPATH //代理CA证书束的路径
CURLOPT_CRLFILE //证书吊销列表
CURLOPT_PROXY_CRLFILE //代理证书吊销列表
CURLOPT_CERTINFO //提取证书信息
CURLOPT_PINNEDPUBLICKEY //设置固定的SSL公钥
CURLOPT_PROXY_PINNEDPUBLICKEY //设置代理的固定SSL公钥
CURLOPT_RANDOM_FILE //为熵随机数据提供源
CURLOPT_EGDSOCKET //识别EGD插座的熵
CURLOPT_SSL_CIPHER_LIST //要使用的密码
CURLOPT_PROXY_SSL_CIPHER_LIST //要使用的代理密码
CURLOPT_TLS13_CIPHERS //要使用的TLS 1.3密码套件
CURLOPT_PROXY_TLS13_CIPHERS //要使用的代理TLS 1.3密码套件
CURLOPT_SSL_SESSIONID_CACHE //禁用SSL会话id缓存
CURLOPT_SSL_OPTIONS //控制SSL行为
CURLOPT_PROXY_SSL_OPTIONS //控制代理SSL行为
CURLOPT_KRBLEVEL //Kerberos安全级别
CURLOPT_GSSAPI_DELEGATION //禁用GSS-API委派
SSH 选型:
CURLOPT_SSH_AUTH_TYPES //SSH身份验证类型
CURLOPT_SSH_COMPRESSION //启用SSH压缩
CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 //主机公钥的MD5
CURLOPT_SSH_PUBLIC_KEYFILE //公钥的文件名
CURLOPT_SSH_PRIVATE_KEYFILE //私钥的文件名
CURLOPT_SSH_KNOWNHOSTS //已知主机的文件名
CURLOPT_SSH_KEYFUNCTION //已知主机处理的回调
CURLOPT_SSH_KEYDATA //传递给ssh密钥回调的自定义指针
OTHER 选项:
CURLOPT_PRIVATE //指向存储的私有指针
CURLOPT_SHARE //共享要使用的对象
CURLOPT_NEW_FILE_PERMS //用于创建新远程文件的模式
CURLOPT_NEW_DIRECTORY_PERMS //用于创建新远程目录的模式
ELNET 选项:
CURLOPT_TELNETOPTIONS //TELNET选项
7. curl_easy_perform 函数
函数: CURLcode curl_easy_perform(CURL *easy_handle);
函数功能:这个函数在初始化CURL类型的指针 以及curl_easy_setopt完成后调用. 运行配置好的选项.
1. CURLE_OK 任务完成一切都好
2. CURLE_UNSUPPORTED_PROTOCOL 不支持的协议,由URL的头部指定
3. CURLE_COULDNT_CONNECT 不能连接到remote 主机或者代理
4. CURLE_REMOTE_ACCESS_DENIED 访问被拒绝
5. CURLE_HTTP_RETURNED_ERROR Http返回错误
6. CURLE_READ_ERROR 读本地文件错误
当使用libcurl发送http请求时,它会自动添加一些http头。我们可以通过CURLOPT_HTTPHEADER属性手动替换、添加或删除相应 的HTTP消息头。
Host http1.1(大部分http1.0)版本都要求客户端请求提供这个信息头。
Pragma "no-cache" 表示不要缓冲数据。
Accept "*/*" 表示允许接收任何类型的数据。
Expect
以POST的方式向HTTP服务器提交请求时,libcurl会设置该消息头为"100-continue",它要求服务器在正式处理该请求之前,返回一 个"OK"消息。如果POST的数据很小,libcurl可能不会设置该消息头。
自定义选项
当前越来越多的协议都构建在HTTP协议之上(如:soap),这主要归功于HTTP的可靠性,以及被广泛使用的代理支持(可以穿透大部分防火墙)。 这些协议的使用方式与传统HTTP可能有很大的不同。对此,libcurl作了很好的支持。
自定义请求方式(CustomRequest)
HTTP支持GET, HEAD或者POST提交请求。可以设置CURLOPT_CUSTOMREQUEST来设置自定义的请求方式,libcurl默认以GET方式提交请求:
curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST");
1. CURLOPT_URL 设置访问URL
2. 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属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。
3.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指针的来源。
4. 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指针来源。
5. CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
跟数据传输进度相关的参数。CURLOPT_PROGRESSFUNCTION 指定的函数正常情况下每秒被libcurl调用一次,为了使CURLOPT_PROGRESSFUNCTION被调用,CURLOPT_NOPROGRESS必须被设置为false,CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的第一个参数
6. CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于设置传输时间,
CURLOPT_CONNECTIONTIMEOUT 设置连接等待时间
7. CURLOPT_FOLLOWLOCATION 设置重定位URL
8. CURLOPT_RANGE: CURLOPT_RESUME_FROM:
断点续传相关设置。
CURLOPT_RANGE 指定char *参数传递给libcurl,用于指明http域的RANGE头域,
例如:
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
CURLOPT_RESUME_FROM 传递一个long参数给libcurl,指定你希望开始传递的 偏移量。
代码写了个小demo,下面是代码片段
struct MemoryStruct{
char *memory;
size_t size;
};
static struct MemoryStruct g_oDataChunk;
static size_t TaskFileCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
printf("%s\n", __func__);
//printf("size == %ld, nmemb == %ld, %s\n", size, nmemb, (char*)ptr);
size_t realsize = 0;
//对文件缓存空间进行处理
realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)data;
mem->memory = (char *)realloc(mem->memory, (mem->size + realsize + 1));
if (mem->memory)
{
memcpy(&(mem->memory[mem->size]), (char*)ptr, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
}
return realsize;
}
static size_t TaskInfoCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = 0;
printf("%s\n", __func__);
printf("size == %ld, nmemb == %ld, %s\n", size, nmemb, (char*)ptr);
realsize = size * nmemb;
//写入数据,数据最大的长度范围是buf的大小
if((realsize) <= MAX_HTTP_BUF_DATA_SIZE)
{
memcpy((char*)data, (char*)ptr, (realsize));
}
else
{
memcpy((char*)data, (char*)ptr, MAX_HTTP_BUF_DATA_SIZE);
}
return realsize;
}
static int http_upgradefile_get_reply(CURL *pCurl)
{
int ret = -1;
static CURLcode res;
static long res_code = 0;
//获取curl执行结果的会话信息
res = curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &res_code);
if((res == CURLE_OK) && (res_code == 200))
{
ret = 0;
}
else if(res_code == 400)
{
printf("res_code 400\n");
ret = -1;
}
else if(res_code == 404)
{
printf("res_code 404\n");
ret = -1;
}
else if(res_code == 500)
{
printf("res_code 500\n");
ret = -1;
}
return ret;
}
static int http_upgradefile_set_ask(CURL *pCurl, char* url, int task)
{
int ret = -1;
static CURLcode res;
struct curl_slist *pList = NULL;
//请求超时时长
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 3L);
//连接超时时长
curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10L);
//允许重定向,使用enable参数控制是否允许URL地址的重定向
curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 1L);
//若启用,会将头文件的信息作为数据流输出
curl_easy_setopt(pCurl, CURLOPT_HEADER, 0L);
//关闭中断信号响应 //如果客户端是多线程的,务必将CURLOPT_NOSIGNAL置为1
curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1L);
//启用时会汇报所有的信息,如果将onoff置为1,那么将使得调用过程中输出更多的关于调用操作的详细信息
curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L);
switch(task)
{
case HTTP_UPGRADEFILE_TASK_ASK_INFO:
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, TaskInfoCallback);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, g_http_buf);
pList = curl_slist_append(pList, "Accept: application/json");
ret = 0;
break;
case HTTP_UPGRADEFILE_TASK_ASK_FILE:
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, TaskFileCallback);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &g_oDataChunk);
pList = curl_slist_append(pList, "Accept: */*");
ret = 0;
break;
default:
ret = -1;
break;
}
curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList); //设置HTTP头
//请求的url地址
curl_easy_setopt(pCurl, CURLOPT_URL, url);
//执行请求, [get]
res = curl_easy_perform(pCurl);
return ret;
}
int http_upgradefile_task(void)
{
int ret = 0;
static CURLcode res;
static CURL *pCurl = NULL;
struct curl_slist *pList = NULL;
static int l_flag = -1;
static long res_code = 0;
//申请内存空间
static struct MemoryStruct *l_pmem = &g_oDataChunk;
l_pmem->memory = (char *)malloc(1);
l_pmem->size = 0;
#if USE_CURL_GLOBAL_FUNC //curl的全局初始化函数调用宏定义
/*
** 该函数用于操作前的全局初始化,它是非线程安全的,它应该在所有其他libcurl函数调用之前被调用,而且只能被调用一次
** 参数:
** CURL_GLOBAL_ALL 初始化除CURL_GLOBAL_ACK_EINTR外的所有系统。
** CURL_GLOBAL_SSL 初始化SSL
** CURL_GLOBAL_WIN32 初始化Win32 socket libraries.
** CURL_GLOBAL_NOTHING 不初始化任何系统
** CURL_GLOBAL_DEFAULT 等同于CURL_GLOBAL_ALL
** CURL_GLOBAL_ACK_EINTR 设置了这个标签后,当curl在连接或等待数据请求时,curl将接收EINTR条件,否则,curl会一直等待。
** 返回值:正常通过时返回0,非零值表示出现错误
*/
res = curl_global_init(CURL_GLOBAL_ALL);
if(CURLE_OK != res)
{
printf("curl global init failed");
ret = -1;
}
else
{
#endif
//外部接口,用于创建,分配并返回一个初始化的CURL句柄,作为其他curl_easy函数的作用对象
pCurl = curl_easy_init();
if(NULL == pCurl)
{
printf("init CURL failed");
ret = -1;
}
else
{
HTTP_BUF_CLEAR(g_http_buf); //清空接收的缓存区
//测试发送第一次
ret = http_upgradefile_set_ask(pCurl, g_url1, HTTP_UPGRADEFILE_TASK_ASK_INFO); //发送给web端请求
ret = http_upgradefile_get_reply(pCurl); //获取到web端应答
if(ret == -1)
{
printf("http_upgradefile_get_reply error\n");
}
else if(ret == 0)
{
printf("http_upgradefile_get_reply finished\n");
printf("%s\n\n", g_http_buf);
//3.开启第二次发送flag
l_flag = 0;
}
if((-1 != l_flag) && (0 == l_flag)) //判断flag非-1,等于0时进行的处理,后续可扩展其他值进行其他的处理
{
//测试发送第二次
ret = http_upgradefile_set_ask(pCurl, g_url2, HTTP_UPGRADEFILE_TASK_ASK_FILE); //发送给web端请求
ret = http_upgradefile_get_reply(pCurl); //获取到web端应答
if(ret == -1)
{
printf("http_upgradefile_get_reply error\n");
}
else if(ret == 0)
{
FILE *l_fp = fopen(g_upgrade_filename,"wb");
if(!l_fp)
{
printf("open file failed");
}
else
{
if((l_pmem->size > 0) && (l_pmem->memory != NULL))
{
//获取到正确应答数据后,进行下一步处理
fwrite(l_pmem->memory, 1, l_pmem->size, l_fp);
//等待数据写完
fflush(l_fp);
}
fclose(l_fp);
printf("http_upgradefile_get_reply finished\n");
}
}
}
//用于释放之前curl_slist中数据
curl_slist_free_all(pList);
pList = NULL;
//调用该函数来结束一个curl easy会话。关闭一个由curl_easy_init()生成的handle
curl_easy_cleanup(pCurl);
pCurl = NULL;
}
#if USE_CURL_GLOBAL_FUNC //libcurl库初始化
curl_global_cleanup();
}
#endif
//释放malloc申请的内存空间
free(l_pmem->memory);
l_pmem->memory = NULL;
l_pmem = NULL;
return ret;
}