分类: 系统运维
2009-05-02 00:01:57
libcur官方主页:http://curl.haxx.se/libcurl/
libcurl为一个免费开源的客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP,跨平台,支持Windows,Unix,Linux等,线程安全,支持Ipv6。
libcurl编程流程:
首先,调用函数curl_global_init()来初始化库函数;
调用curl_easy_init()来初始化一个句柄,得到一个easy interface型指针;
接着,再调用curl_easy_setopt来设置将要访问的网络地址,当然还有许多其它的选项可以设置,这是libcurl编程的重点。
返回的数据怎样传给客户端应用程序呢?
先自己写一个回调函数,然后把这个回调函数通过curl_easy_setopt设置到libcurl库里。再指定是什么的数据格式接收,当libcurl库返回数据时就会回调设置的函数。
定义回调函数:
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
设置回调函数
curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);
设置回调函数接收的数据格式
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);
通过调用curl_easy_perform来连接远程的网站,开始协议相关的操作,libcurl库启动下载或上传数据。
libcurl curl_easy_setopt()说明
CURLOPT_VERBOSE
设置这个选项的参数为1,libcurl会显示出一些操作的详细信息。这对于libcurl和协议的调试和理解很有帮助。
CURLOPT_HTTPHEADER
构造HTTP头部字段,或代替现有字段(从而移除已有字段)。该选项传递一个指针,这个指针指向HTTP请求中传给server的头部字段链表(linked list)。用curl_slist_append(3)来创建头部字段list,curl_slist_free(3)用来清除list 。例如:增加User-Authertication这个头部字段。
使用libcurl设置HTTP头部字段的方法:
#include
Struct curl_slist
*slist = NULL;
Slist =
curl_slist_append(slist, “User-Authentication:xxxxxxxx”);
Curl_easy_setopt(handle,
CURLOPT_HTTPHEADER, slist);
Curl_easy_perform(handle);
Curl_slist_free_all(slist);
xxxxxxx代表具体的头部设置内容。
CURLOPT_PUT/CURLOPT_UPLOAD
设置这个选项为1,让libcurl使用HTTP PUT来传输数据。从
CURLOPT_READDATA
设置传递给读函数的数据指针。如果使用了 CURLOPT_WRITEFUNCTION 参数, 可以使用这个指针作为输入,如果没有使用CURLOPT_WRITEFUNCTION, 则必需给出一个FILE*类型指针, libcurl会将其传递给fwrite()。
在
CURLOPT_INFILESIZE
当向远程站点上传文件时,这个选项用来设置上传文件的大小。
CURLOPT_POST
这个选项设置为1,告知libcurl执行HTTP POST操作。
默认libcurl会使用"Content-Type:
application/x-www-form-urlencoded"头部字段,你也可以用CURLOPT_HTTPHEADER选项来更改这个字段。使用HTTP1.1的POST方法意味着使用"Expect:
100-continue"字段,你也可以用CURLOPT_HTTPHEADER来取消这个字段。
可以设置CURLOPT_READFUNCTION 和CURLOPT_READDATA选项来为POST提供数据,同时,不能再设置CURLOPT_POSTFIELDS选项。当使用callback函数来提供数据时,一定要使用大块数据传输编码(chunked transfer-encoding)或者用CURLOPT_POSTFIELDSIZE 或CURLOPT_POSTFIELDSIZE_LARGE选项设置数据大小。chunked transfer-encoding可以用CURLOPT_HTTPHEADER来设置字段。
如果使用了POST请求方法,想要用同一个handle来GET或HEAD,必须用CURLOPT_NOBODY
或CURLOPT_HTTPGET选项来设置新的请求方法。
CURLOPT_WRITEFUNCTION
设置指向回调函数的指针,回调函数原型如下:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
当libcurl接收到要保存的数据时调用此函数, 因此该函数多作数据保存的功能,如处理下载文件。ptr所指数据大小为 size*nmemb. 返回实际处理的数据大小,如果返回值不等于传递给函数的数据大小,则报错,并返回CURLE_WIRTE_ERROR。
如果此选项的参数设置为NULL, 则会调用默认的函数,将数据写入到FILE*(由CURLOPT_WRITEDATA 给出)
此回调函数会尽量处理更多数据,但是传递给回调函数的数据最大值定义在curl.h文件中。
CURLOPT_WRITEDATA
在
FILE *fp;
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
int written;
written = fwrite(ptr, size, nmemb, (FILE *)fp);
return written;
}
CALLBACK OPTIONS
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指针的来源。
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指针来源。
HTTP OPTIONS
CURLOPT_POSTFIELDS
作用:描述传输的数据,必须确保传输的数据服务器可以解析,libcurl不会转化或encode,但是大部分服务器假定这些数据是url-encoded,
此选项使用后POST是一个application/x-www-form-urlencoded类型。
CURLOPT_COOKIEJAR
作用:在关闭链接的时候把cookie写入指定的文件
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "/tmp/cookie.txt");
CURLOPT_COOKIEFILE
作用:取用现有的cookie,而不重新得到cookie
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");
CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
CURLOPT_TIMEOUT 由于设置传输时间,CURLOPT_CONNECTIONTIMEOUT 设置连接等待时间
使用libcurl编程应用实例(源码没有贴出来,有兴趣的可以一起分享)
在使用libcurl编程时,当使用gcc编译源程序的时候,不要忘记-lcurl这一选项。
实例一:获取HTML文件,标准输出到显示器。源代码见/home/code/get_http.c
编译源代码gcc
get_http.c -o get_http -lcurl
运行程序获取百度主页HTML文件:./get_http
实例二:把获取的HTML文件保存在本地机。源代码见/home/code/save_http.c
编译运行程序:
[root@localhost lp]# gcc save_http.c -o save_http -lcurl
[root@localhost lp]# ./save_http /home/tmp/2009baidu
* About to connect() to port 80 (#0)
* Trying 119.75.213.36... * connected
* Connected to (119.75.213.36) port 80 (#0)
> GET / HTTP/1.1
Host:
Accept: */*
< HTTP/1.1 200 OK
< Date: Sat, 07 Mar 2009 05:06:32 GMT
< Server: BWS/1.0
< Content-Length: 3596
< Content-Type: text/html
< Cache-Control: private
< Expires: Sat, 07 Mar 2009 05:06:32 GMT
< Set-Cookie: BAIDUID=59B575E3904A271180835C0F76FD11F6:FG=1; expires=Sat,
07-Mar-39 05:06:32 GMT; path=/; domain=.baidu.com
< P3P: CP=" OTI DSP COR IVA OUR IND COM "
<
* Connection #0 to host left intact
Closing connection #0
实例三:上传文件到FTP服务器。源代码见/home/code/ftp_upload.c
编译运行程序:
[root@localhost lp]# gcc ftp_upload.c -o ftp_upload -lcurl
[root@localhost lp]# ./ftp_upload ftp://ccliu:123456@59.64.151.82/test1
/home/tmp/holdon
* About to connect() to 59.64.151.82 port 21 (#0)
* Trying 59.64.151.82... * connected
* Connected to 59.64.151.82 (59.64.151.82) port 21 (#0)
< 220 Serv-U FTP Server v7.0 ready...
> USER ccliu
< 331 User name okay, need password.
> PASS 123456
< 230 User logged in, proceed.
> PWD
< 257 "/" is current directory.
* Entry path is '/'
> EPSV
* Connect data stream passively
< 500 'EPSV': command not understood.
* disabling EPSV usage
> PASV
< 227 Entering Passive Mode (59,64,151,82,4,205)
* Trying 59.64.151.82... * connected
* Connecting to 59.64.151.82 (59.64.151.82) port 1229
> TYPE I
< 200 Type set to I.
> SIZE test1
< 550 /test1: No such file.
> STOR test1
< 150 Opening BINARY mode data connection for test1.
< 226 Transfer complete. 3,030,276 bytes transferred. 8,243.05 KB/sec.
* Uploaded unaligned file size (3030276 out of 4297997572 bytes)
* Connection #0 to host 59.64.151.82 left intact
* Transferred a partial file
Speed: 6730342.000 bytes/sec during 0.450 seconds
Transferred a partial file
> QUIT
< 221 Goodbye, closing session.
Closing connection #0
实例四:从FTP服务器上下载文件。源代码见/home/code/download.c,FTP下载时,不需要设置重定向、浏览器、代理等。该程序在从网站服务器下载文件时有待改进,如从百度下载mp3。
编译运行程序:
[root@localhost lp]# gcc download.c -o download -lcurl
[root@localhost lp]# ./download ftp://ccliu:123456@59.64.151.82/test
/home/mlt/test
* About to connect() to 59.64.151.82 port 21 (#0)
* Trying 59.64.151.82... * connected
* Connected to 59.64.151.82 (59.64.151.82) port 21 (#0)
< 220 Serv-U FTP Server v7.0 ready...
> USER ccliu
< 331 User name okay, need password.
> PASS 123456
< 230 User logged in, proceed.
> PWD
< 257 "/" is current directory.
* Entry path is '/'
> EPSV
* Connect data stream passively
< 500 'EPSV': command not understood.
* disabling EPSV usage
> PASV
< 227 Entering Passive Mode (59,64,151,82,4,218)
* Trying 59.64.151.82... * connected
* Connecting to 59.64.151.82 (59.64.151.82) port 1242
> TYPE I
< 200 Type set to I.
> SIZE test
< 213 1515138
> RETR test
< 150 Opening BINARY mode data connection for test (1515138 Bytes).
* Maxdownload = -1
* Getting file with size: 1515138
< 226 Transfer complete. 1,515,138 bytes transferred. 8,652.79 KB/sec.
* Connection #0 to host 59.64.151.82 left intact
> QUIT
< 221 Goodbye, closing session.
* Closing connection #0
参考网站:
[1]各种HTTP/FTP客户端开发库http://blog.csdn.net/heiyeshuwu/archive/2007/07/15/1691904.aspx
[2]Libcurl编程
[3]Libcurl编程手册及代码实例
http://www.maycode.com/index.php/linux/54-linuxdevelop/1151-curl.html
[4]Simplify Network Programming with libCURL
http://www.linuxdevcenter.com/pub/a/linux/2005/05/05/libcurl.html
[5]libcurl note(Http应用)及API介绍http://blog.chinaunix.net/u2/61797/article_82446.html
[6]libcurl使用的简单例子http://blog.chinaunix.net/u/27904/showart_462499.html