Linux下的libcurl库的使用(学习总结)

Linux下的libcurl库的使用(学习总结)

由于这两天弄一个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;
}

你可能感兴趣的:(linux,ubuntu,unix)