libcurl学习笔记

首先几个关键的函数:

curl_global_init();     //全局初始化
curl_easy_init();       //初始化一个easy handle
curl_easy_setopt();     //给easy handle设置参数
curl_easy_perform();    //执行easy handle,阻塞式的
curl_easy_cleanup();    //销毁easy handle

curl_global_cleanup();  //清理全局

大致流程如此:


程序开始时执行curl_global_init(),初始化libcurl要用到的一系列环境
调用curl_easy_init(),初始化一个easy handle
使用curl_easy_setopt()给easy handle设置一些http传输的参数,比如设置url,设置传输完成接收到的数据怎么处理,设置http头部等
curl_easy_perform()字如其名,真正开始进行http通信了
如果你还需要继续进行http通信的话,再次调用curl_easy_perform
任务完成了,调用curl_easy_cleanup(),释放掉easy handle所占用的内存
不再需要使用libcurl时,调用curl_global_cleanup()释放内存


CURLcode curl_global_init(long flags);

flags取值: 
CURL_GLOBAL_ALL: 初始化全部可能要用到的功能,<推荐>
CURL_GLOABL_WIN32: 在windows平台使用
CURL_GLOBAL_SSL: 使用ssl库,支持https的话用这个(前提是,编译libcurl的时候添加了支持的ssl的选项)


1.这个函数只需要被执行一次。
2.当你没有显式调用这个函数的话,这个函数将会在你调用curl_easy_init()的时候被自动执行
3.一般情况下,没有调用这个函数而在curl_easy_init()中被隐式调用是没有问题的,但是当多线程的情况下,则可能会出现被多次调用的问题
4.所以,还是手动调用一次比较稳妥

CURL *curl_easy_init(void);
返回值: 一个CURL类型的指针


CURLcode curl_easy_setopt(CURL *handle, opt, param);

handle: curl_easy_init()函数初始化返回的easy handle
opt和param相对应:


CURLOPT_URL: 对应一个url字符串,也就是想要请求的url地址
CURLOPT_VERBOSE: 对应1,表示要求输出调试信息(是libcurl内部另开一个线程输出的)
CURLOPT_DEBUGFUNCTION: 表示调试信息要输出的级别


CURLOPT_WRITEFUNCTION: 设置回调函数,这个回调函数将在内部socket一旦接收到数据时被调用
        (**注意并不是接收到全部数据才被调用,而是只要接收到数据就调用,数据大时将会被多次调用**)
        例子: curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, back);
        回调函数的原型:
        size_t back(void *buffer, size_t size, size_t nmemb, void *userpt);
        buffer: 执行接收到的数据的首地址 
        size: 接收到的每一个数据项的字节数
        nmemb: 接收到的数据项的个数
        userpt: 用户可以自由使用的指针,一般是用来传递一个文件指针,用来在函数体内部保存数据


CURLOPT_HTTPHEADER: 设置http请求的头部
        例子:curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
        headers: 一个curl_slist类型的指针,设置方法如下:
        struct curl_slist *headers = NULL;//必须被赋予NULL
        headers = curl_slist_append(headers, "Hey-server-hey: how are you?");
        headers = curl_slist_append(headers, "X-silly-content: yes");
        当设置的请求头字段与内部预定义的字段相重合时,内部预定义的内容将被替换为用户设置的,如果想要删除某个内部预定义的头字段时
        headers = curl_slist_append(headers, "Host:");
        采用这种形式,冒号后不添加任何字符


CURLOPT_CUSTOMREQUEST: 自定义请求方式,默认不post任何数据时,请求方式为GET
        例子:curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "HAHA");


CURLOPT_COOKIE: 设置要发送时携带的COOKIE字段,但是似乎直接设置头部时写上cookie字段,也是没有问题的,两种方法都行
        例子:curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
CURLOPT_COOKIEFILE: 动态的设置cookie
        例子:
        FILE *file = fopen("/dev/null", "r");
        curl_easy_setopt(handle, CURLOPT_COOKIEFILE, file);
        当一个easy handle被设置了此选项时,手动的添加cookie将会被忽略。
        当easy handle访问了一次页面后,如果response的头部有set-cookie字段时,这个cookie将会被保存在对应的文件中,当再次调用这个easy handle时,easy handle将会从这个文件中查找对应域名的cookie,如果找到了,将会自动添加找到的cookie到request头部。
        如果这个文件指针指向一个不存在的文件,那么将会保存获得cookie到内存中,通常这是一种常用的做法


CURLOPT_FOLLOWLOCATION:设置跟随重定向
        当libcurl被设置为1时,如果libcurl接收到了一个response是重定向的,此时,libcurl将会自动跟随到这个重定向指定的地址


CURLOPT_POSTFIELDS: POST数据
        post字符数据的例子:
        char *data="name=daniel&project=curl";
        curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
        一种超级简单的方式,就post了数据,但是这只能post字符数据
        post二进制数据的例子:
        struct curl_slist *headers=NULL;
headers = curl_slist_append(headers, "Content-Type: text/xml");
        curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, binaryptr);
        curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23L);
        curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
        当CURLOPT_POSTFIELDS选项被设置后,libcurl自动将请求方式变更为POST
        这似乎是件好事,但是由于easy handle上面设置的属性的是不会随着perform之后而自动复位的,所以当下一次要进行GET请求时,需要手动更改请求方式为GET
         curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);
         或者
         curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "GET");


CURLOPT_HTTP_VERSION: 设置libcurl所使用的http版本
        默认是使用http1.1的版本,可以通过设置成1.0的版本
        1.1的版本支持长连接,也就是建立一次tcp连接,可以进行n多次http通信
        1.0的版本只能够一个tcp连接,一次http通信,如果想要继续通信,则需要重新建立tcp连接
        例子:curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);


代理设置:
curl_easy_setopt(easyhandle, CURLOPT_PROXY, "proxy-host.com:8080");  //当被设置为空字符串时,将会禁用代理
当代理需要认证时:
curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "user:password"); 


超时设置:
CURLOPT_TIMEOUT: 设置获取内容超时秒数(tcp连接已建立,但是获取http返回内容超时)
CURLOPT_TIMEOUT_MS: 同上,只是这个设置的单位是毫秒
CURLOPT_CONNECTTIMEOUT: 设置tcp连接建立的超时秒数(建立tcp连接时超时)
CURLOPT_CONNECTTIMEOUT_MS: 同上,只是这个设置的单位是毫秒



附URLCODE状态码:

转自:curl返回常见错误码

CURLE_OK(0)

成功。

CURLE_UNSUPPORTED_PROTOCOL(1) 
你的URL传递给libcurl的使用协议,这libcurl的不支持。支持可能是你没有使用一个编译时的选项,它可以是一个拼写错的协议字符串,或者只是一个协议的libcurl没有代码。

CURLE_FAILED_INIT(2) 
非常早期的初始化代码失败。这可能是内部错误或问题,资源问题,一些基本的东西可能无法完成初始化时间。

CURLE_URL_MALFORMAT(3) 
该网址的格式不正确。

CURLE_NOT_BUILT_IN(4) 
libcurl的内置在​​一个编译时决定所要求的功能,协议或购股权没有被发现。这意味着,一个功能或选项是不启用或明确禁用的libcurl建时,为了得到它的功能,你必须得到一个重建的libcurl的。

CURLE_COULDNT_RESOLVE_PROXY(5) 
无法解析代理服务器。代理主机无法得到解决。

CURLE_COULDNT_RESOLVE_HOST(6) 
无法解析主机。给定的远程主机没有得到解决。

CURLE_COULDNT_CONNECT(7) 
connect()的主机或代理失败。

CURLE_FTP_WEIRD_SERVER_REPLY(8) 
连接到一个FTP服务器后,libcurl的预期得到一定的回复返回。这个错误代码表示,它有一个奇怪的或坏的答复。指定的远程服务器可能不是一个确定的FTP服务器。

CURLE_REMOTE_ACCESS_DENIED(9) 
我们被拒绝访问的资源的URL。对于FTP,发生这种情况而力图改变的远程目录。

CURLE_FTP_ACCEPT_FAILED(10) 
在等待服务器的连接时,一个主动FTP会话使用,被送到控制连接或类似的错误代码。

CURLE_FTP_WEIRD_PASS_REPLY(11) 
发送到服务器的FTP密码后,libcurl的预计正确的答复。此错误代码指示返回了意外的代码。

CURLE_FTP_ACCEPT_TIMEOUT(12) 
在当前的FTP会话在等待服务器连接,CURLOPT_ACCEPTTIMOUT_MS(或内部默认),超时过期。

CURLE_FTP_WEIRD_PASV_REPLY(13) 
libcurl的失败作为一个PASV或EPSV命令从服务器得到一个合理的结果。服务器是有缺陷的。

CURLE_FTP_WEIRD_227_FORMAT(14) 
FTP服务器返回一个227行作为一个PASV命令的响应。如果libcurl的无法解析该行,此返回代码被传递回。

CURLE_FTP_CANT_GET_HOST(15) 
内部故障查找主机使用新的连接。

CURLE_FTP_COULDNT_SET_TYPE(17) 
收到一个错误,当试图传送模式设置为二进制或ASCII。

CURLE_PARTIAL_FILE(18) 
文件传输,短于或大于预期。发生这种情况时,服务器首先报告预期的传输大小,然后提供数据不匹配前面给出的大小。

CURLE_FTP_COULDNT_RETR_FILE(19) 
这是一个奇怪的回答“RETR”命令或一个零字节传输完成。

CURLE_QUOTE_ERROR(21) 
当发送到远程服务器,自定义的“QUOTE”命令的一个命令返回的错误代码为400或更高(对于FTP)或表示不成功的完成命令。

CURLE_HTTP_RETURNED_ERROR(22) 
这是返回CURLOPT_FAILONERROR设置为TRUE和HTTP服务器返回的错误代码是> = 400。

CURLE_WRITE_ERROR(23) 
发生错误,写作时接收到的数据到本地文件,或者返回错误libcurl的一个写回调。

CURLE_UPLOAD_FAILED(25) 
开始上载失败。对于FTP,服务器通常否认的STOR命令。通常的错误缓冲区包含了服务器的解释。

CURLE_READ_ERROR(26) 
有一个问题读取本地文件或返回一个错误的读回调。

CURLE_OUT_OF_MEMORY(27) 
内存分配请求失败。这是严重的不良和活动,如果发生过严重搞砸了。

CURLE_OPERATION_TIMEDOUT(28) 
操作超时。根据条件达到指定的超时期间。

CURLE_FTP_PORT_FAILED(30) 
FTP PORT命令返回错误。这主要是当你还没有足够的地址指定了一个良好的libcurl的使用。SeeCURLOPT_FTPPORT。

CURLE_FTP_COULDNT_USE_REST(31) 
FTP REST命令返回错误。如果服务器是明智的,这不应该发生。

CURLE_RANGE_ERROR(33) 
服务器不支持或接受范围请求。

CURLE_HTTP_POST_ERROR(34) 
这是一个奇怪的错误,主要发生是由于内部的混乱。

CURLE_SSL_CONNECT_ERROR(35) 
出现问题的地方,在SSL / TLS握手。你真正想要的的错误缓冲区和阅读邮件,因为它针对问题稍微。可能是证书(文件格式,路径,权限),密码,和其他人。

CURLE_BAD_DOWNLOAD_RESUME(36) 
下载无法恢复,因为指定的偏移量为文件的边界。

CURLE_FILE_COULDNT_READ_FILE(37) 
无法打开的文件FILE :/ /。最有可能的,因为该文件的路径不能识别现有文件。你是否检查文件的权限?

CURLE_LDAP_CANNOT_BIND(38) 
LDAP无法绑定。LDAP绑定操作失败。

CURLE_LDAP_SEARCH_FAILED(39) 
LDAP搜索失败。

CURLE_FUNCTION_NOT_FOUND(41) 
函数没有找到。一个必需的zlib的功能没有被发现。

CURLE_ABORTED_BY_CALLBACK(42) 
通过回调中止。返回的回调“中止”libcurl的。

CURLE_BAD_FUNCTION_ARGUMENT(43) 
内部错误。函数调用了一个错误的参数。

CURLE_INTERFACE_FAILED(45) 
接口错误。指定的出接口不能使用。设置接口使用传出连接的源IP地址与CURLOPT_INTERFACE。

CURLE_TOO_MANY_REDIRECTS(47) 
过多的重定向。以下重定向时,libcurl的创下的最高金额。设置您的与CURLOPT_MAXREDIRS限制。

CURLE_UNKNOWN_OPTION(48) 
无法识别的选项传递给libcurl的/。请参阅相应的文档。这是最有可能在程序中使用libcurl的问题。的的错误缓冲区可能包含准确的选项,它涉及更具体的信息。

CURLE_TELNET_OPTION_SYNTAX(49) 
telnet选项字符串被非法格式化。

CURLE_PEER_FAILED_VERIFICATION(51) 
远程服务器的SSL证书或SSH的MD5指纹被认为是不正常的。

CURLE_GOT_NOTHING(52) 
没有从服务器返回的,和得到什么的情况下,被认为是一个错误。

CURLE_SSL_ENGINE_NOTFOUND(53) 
未找到指定的加密引擎。

CURLE_SSL_ENGINE_SETFAILED(54) 
设置所选的SSL加密引擎,默认情况下失败!

CURLE_SEND_ERROR(55) 
发送网络数据失败。

CURLE_RECV_ERROR(56) 
如果接收网络数据。

CURLE_SSL_CERTPROBLEM(58) 
与当地的客户端证书的问题。

CURLE_SSL_CIPHER(59) 
无法使用指定的密码。

CURLE_SSL_CACERT(60) 
同侪凭证不能与已知的CA证书进行身份验证。

CURLE_BAD_CONTENT_ENCODING(61) 
无法识别的传输编码。

CURLE_LDAP_INVALID_URL(62) 
无效的LDAP URL。

CURLE_FILESIZE_EXCEEDED(63) 
最大文件大小超过。

CURLE_USE_SSL_FAILED(64) 
要求FTP SSL水平失败。

CURLE_SEND_FAIL_REWIND(65) 
在做了一个发送操作卷曲,倒带重传的数据,但的倒带操作失败。

CURLE_SSL_ENGINE_INITFAILED(66) 
SSL发动机启动失败。

CURLE_LOGIN_DENIED(67) 
远程服务器拒绝卷曲登录(加入7.13.1)

CURLE_TFTP_NOTFOUND(68) 
TFTP服务器上找不到文件。

CURLE_TFTP_PERM(69) 
TFTP服务器上的权限问题。

CURLE_REMOTE_DISK_FULL(70) 
出在服务器上的磁盘空间。

CURLE_TFTP_ILLEGAL(71) 
非法的TFTP操作。

CURLE_TFTP_UNKNOWNID(72) 
未知TFTP传输ID。

CURLE_REMOTE_FILE_EXISTS(73) 
文件已经存在,并不会被覆盖。

CURLE_TFTP_NOSUCHUSER(74) 
这个错误不应该被返回正常工作的TFTP服务器。

CURLE_CONV_FAILED(75) 
字符转换失败。

CURLE_CONV_REQD(76) 
调用者必须注册转换回调。

CURLE_SSL_CACERT_BADFILE(77) 
问题读取SSL证书(路径的访问权限?)

CURLE_REMOTE_FILE_NOT_FOUND(78) 
不存在的URL引用的资源。

CURLE_SSH(79) 
未指定的错误发生在SSH会话。

CURLE_SSL_SHUTDOWN_FAILED(80) 
关闭SSL连接失败。

CURLE_AGAIN(81) 
Socket是没有准备好发送/接收等待,直到它准备好了,然后再试一次。此返回代码仅返回从 curl_easy_recv(3) 和 (3) (加入7.18.2 curl_easy_send),

CURLE_SSL_CRL_BADFILE(82) 
无法加载CRL文件(在7.19.0版加入)

CURLE_SSL_ISSUER_ERROR(83) 
发行人检查失败(在7.19.0版加入)

CURLE_FTP_PRET_FAILED(84) 
FTP服务器不理解的PRET命令,所有不支持给定的参数。要小心时usingCURLOPT_CUSTOMREQUEST,自定义列表“命令将发送PRET CMD前PASV以及。(添加在7.20.0)

CURLE_RTSP_CSEQ_ERROR(85) 
RTSP的Cseq号码不匹配。

CURLE_RTSP_SESSION_ERROR(86) 
RTSP会话标识符不匹配。

CURLE_FTP_BAD_FILE_LIST(87) 
无法,解析FTP文件列表(在FTP通配符下载)。

CURLE_CHUNK_FAILED(88) 
块回调报告错误。

CURLE_OBSOLETE * 
这些错误代码永远不会返回。它们被用来在一个老的libcurl版本,当前未使用




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值