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版本,当前未使用