如何php curl 使用代理curl的代理

使用curl库通过代理服务器访问网页-php-电脑编程网使用curl库通过代理服务器访问网页作者:佚名 和相关&&
&?function curl_string ($url,$user_agent,$proxy){$ch = curl_init();curl_setopt ($ch, CURLOPT_PROXY, $proxy);curl_setopt ($ch, CURLOPT_URL, $url);curl_setopt ($ch, CURLOPT_USERAGENT, $user_agent);curl_setopt ($ch, CURLOPT_COOKIEJAR, "c:\cookie.txt");curl_setopt ($ch, CURLOPT_HEADER, 1);curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);curl_setopt ($ch, CURLOPT_TIMEOUT, 120);$result = curl_exec ($ch);curl_close($ch);return $}$url_page = "http://www.366edu.net";$user_agent = "Mozilla/4.0";$proxy = "http://192.11.222.124:8000";$string = curl_string($url_page,$user_agent,$proxy);echo $?&相关资料:|||||||使用curl库通过代理服务器访问网页来源网络,如有侵权请告知,即处理!编程Tags:                &                    > 求解libcurl取回来网页.以及代理设置方法
求解libcurl取回来网页.以及代理设置方法
ttwwsophia & &
发布时间: & &
浏览:6 & &
回复:1 & &
悬赏:0.0希赛币
求解libcurl取返回网页.以及代理设置方法定义一个函数
string&getweb(url:string,proxy:string)
//使得最后返回的是网页的HTML代码.错误则返回空.
&&&&curl&=&curl_easy_init();&&&&&&&&//初始化一个CURL类型的指针
&&&&if(curl!=NULL)
&&&&&&&&curl_easy_setopt(curl,&CURLOPT_URL,&url);&&&&&&&&
&&&&&&&&res&=&curl_easy_perform(curl);
&&&&&&&&curl_easy_cleanup(curl);
不过我这样只能打印在屏幕上..不能作为返回.
网上翻了很多.只找到保存到文件的方法,而且必须要回调函数...
有没有直接可以返回的
我记得以前PHP可以用缓冲区..
另外求代理设置方法
引用:  #define&MAX_BUF& &65536
char&wr_buf[MAX_BUF+1];
void&test()&
&&&&if&(curl)&{
&curl_easy_setopt(curl,&CURLOPT_COOKIEFILE,&"d:/cookie.txt");&//&指定cookie文件
&curl_easy_setopt(curl,&CURLOPT_COOKIEJAR,&"d:/cookie.txt");
&curl_easy_setopt(curl,&CURLOPT_HTTPHEADER,&headers&);
&curl_easy_setopt(curl,&CURLOPT_URL,&sign_url);&&&//&指定url
&curl_easy_setopt(curl,&CURLOPT_READDATA,&(void&*)&wr_error);
&curl_easy_setopt(curl,&CURLOPT_WRITEFUNCTION,&write_data&);//调用写回调
&/*&Allow&curl&to&perform&the&action&*/
&res&=&curl_easy_perform(curl);
&printf(&"ret&=&%d&(write_error&=&%d)\n",&res,&wr_error&);
&&/*&Emit&the&page&if&curl&indicates&that&no&errors&occurred&*/
&if&(&res&==&0&)&
printf(&"%s\n",&wr_buf&);
&curl_slist_free_all(headers);
&curl_easy_cleanup(curl);
&*&Write&data&callback&function&(called&within&the&context&of
&*&curl_easy_perform.ttyanwang & &
19:55:57 & &
& & (0)(0)引用
本问题标题:
本问题地址:
温馨提示:本问答中心的任何言论仅代表发言者个人的观点,与希赛网立场无关。请对您的言论负责,遵守中华人民共和国有关法律、法规。如果您的言论违反希赛网问答中心的规则,将会被删除。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&您的浏览器已经禁用了脚本,这会严重影响您正常使用本站的功能,请开启!
当前位置: &
curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。
curl(选项)(参数)
-a/--append
上传文件时,附加到目标文件
-A/--user-agent &string&
设置用户代理发送给服务器
可以使用&任何&身份验证方法
-b/--cookie &name=string/&
cookie字符串或文件读取位置
& & &--basic
使用HTTP基本验证
-B/--use-ascii
使用ASCII /文本传输
-c/--cookie-jar &file&
操作结束后把cookie写入到这个文件中
-C/--continue- &offset&
-d/--data &data&
HTTP POST方式传送数据
& & &--data-ascii &data&
以ascii的方式post数据
& & &--data-binary &data&
以二进制的方式post数据
& & &--negotiate
使用HTTP身份验证
& & &--digest
使用数字身份验证
& & &--disable-eprt
禁止使用EPRT或LPRT
& & &--disable-epsv
禁止使用EPSV
-D/---header &file&
把header信息写入到该文件中
& & &--egd-file &file&
为随机数据(SSL)设置EGD socket路径
& & &--tcp-nodelay
使用TCP_NODELAY选项
-e/--referer
-E/--cert &cert[:]&
客户端证书文件和密码 (SSL)
& & &--cert- &type&
证书文件类型 (DER/PEM/ENG) (SSL)
& & &--key &key&
私钥文件名 (SSL)
& & &--key-type &type&
私钥文件类型 (DER/PEM/ENG) (SSL)
& & &--pass &pass&
私钥密码 (SSL)
& & &--engine &eng&
加密引擎使用 (SSL). &--engine list& for list
& & &--cacert &file&
CA证书 (SSL)
& & &--capath &directory&
CA目录 (made using c_rehash) to verify peer against (SSL)
& & &--ciphers &list&
& & &--compressed
要求返回是压缩的形势 (using deflate or )
& & &--connect-timeout &seconds&
设置最大请求时间
& & &--create-
建立本地目录的目录层次结构
& & &--crlf
上传是把LF转变成CRLF
连接失败时不显示http错误
& & &--ftp-create-dirs
如果远程目录不存在,创建远程目录
& & &--ftp-method [multicwd/nocwd/singlecwd]
控制CWD的使用
& & &--ftp-pasv
使用 PASV/EPSV 代替端口
& & &--ftp-skip-pasv-
使用PASV的时候,忽略该IP地址
& & &--ftp-ssl
尝试用 SSL/TLS 来进行ftp数据传输
& & &--ftp-ssl-reqd
要求用 SSL/TLS 来进行ftp数据传输
-F/--form &name=content&
模拟http表单提交数据
& & &--form-string &name=string&
模拟http表单提交数据
-g/--globoff
禁用网址序列和范围使用{}和[]
以get的方式来发送数据
-H/--header &line&
自定义头信息传递给服务器
& & &--ignore-content-length
忽略的HTTP头信息的长度
-i/--include
输出时包括protocol头信息
只显示请求头信息
-j/--junk-session-cookies
读取文件进忽略session cookie
& & &--interface &interface&
使用指定网络接口/地址
& & &--krb4 &level&
使用指定安全级别的krb4
-k/--insecure
允许不使用证书到SSL站点
-K/--config
指定的配置文件读取
-l/--list-only
列出ftp目录下的文件名称
& & &--limit-rate &rate&
设置传输速度
& & &--local-port&NUM&
强制使用本地端口号
-m/--max- &seconds&
设置最大传输时间
& & &--max-redirs &num&
设置最大读取的目录数
& & &--max-filesize &bytes&
设置最大下载的文件总量
-M/--manual
显示全手动
-n/--netrc
从netrc文件中读取用户名和密码
& & &--netrc-optional
使用 .netrc 或者 URL来覆盖-n
& & &--ntlm
使用 HTTP NTLM 身份验证
-N/--no-buffer
禁用缓冲输出
-o/--output
把输出写到该文件中
-O/--remote-name
把输出写到该文件中,保留远程文件的文件名
-p/--proxytunnel
使用HTTP代理
& & &--proxy-anyauth
选择任一代理身份验证方法
& & &--proxy-basic
在代理上使用基本身份验证
& & &--proxy-digest
在代理上使用数字身份验证
& & &--proxy-ntlm
在代理上使用ntlm身份验证
-P/--ftp-port &address&
使用端口地址,而不是使用PASV
作为第一个参数,关闭 .curlrc
-Q/--quote &cmd&
文件传输前,发送命令到服务器
-r/--range &range&
检索来自HTTP/1.1或FTP服务器字节范围
--range-file
读取(SSL)的随机文件
-R/--remote-time
在本地生成文件时,保留远程文件时间
& & &--retry &num&
传输出现问题时,重试的次数
& & &--retry-delay &seconds&
传输出现问题时,设置重试间隔时间
& & &--retry-max-time &seconds&
传输出现问题时,设置最大重试时间
-s/--silent
静默模式。不输出任何东西
-S/--show-error
& & &--socks4 &[:port]&
用socks4代理给定主机和端口
& & &--socks5 &host[:port]&
用socks5代理给定主机和端口
& & &--stderr &file&
-t/---option &OPT=val&
Telnet选项设置
& & &--trace &file&
对指定文件进行debug
& & &--trace-ascii &file&
Like --跟踪但没有hex输出
& & &--trace-time
跟踪/详细输出时,添加时间戳
-T/--upload-file &file&
& & &--url &URL&
Spet URL to work with
-u/--user &user[:password]&
设置服务器的用户和密码
-U/--proxy-user &user[:password]&
设置代理用户名和密码
-/---out [format]
什么输出完成后
-x/--proxy &host[:port]&
在给定的端口上使用HTTP代理
-X/--request &&
指定什么命令
-y/--speed-time
放弃限速所要的时间,默认为30
-Y/--speed-limit
停止传输速度的限制,速度时间
curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。如果系统没有curl可以使用
curl安装,也可以下载安装。curl是将下载文件输出到stdout,将进度信息输出到stderr,不显示进度信息使用--silent选项。
curl URL --silent
这条命令是将下载文件输出到终端,所有下载的数据都被写入到stdout。
使用选项-O将下载的数据写入到文件,必须使用文件的绝对地址:
curl http://.linuxde.net/text.iso --silent -O
选项-o将下载数据写入到指定名称的文件中,并使用--progress显示进度条:
curl http://man.linuxde.net/.iso -o filename.iso --progress
######################################### 100.0%
curl能够从特定的文件偏移处继续下载,它可以通过指定一个便宜量来下载部分文件:
curl URL/File -C 偏移量
#偏移量是以字节为单位的整数,如果让curl自动推断出正确的续传位置使用-C -:
curl -C -URL
使用curl设置参照页字符串
参照页是位于HTTP头部中的一个字符串,用来表示用户是从哪个页面到达当前页面的,如果用户点击网页A中的某个连接,那么用户就会跳转到B网页,网页B头部的参照页字符串就包含网页A的URL。
使用--referer选项指定参照页字符串:
curl --referer
http://man.linuxde.net
用curl设置cookies
使用--cookie &COKKIES&选项来指定cookie,多个cookie使用分号分隔:
curl http://man.linuxde.net --cookie &user=pass=123456&
将cookie另存为一个文件,使用--cookie-jar选项:
curl URL --cookie-jar cookie_file
用curl设置用户代理字符串
有些网站访问会提示只能使用IE浏览器来访问,这是因为这些网站设置了检查用户代理,可以使用curl把用户代理设置为IE,这样就可以访问了。使用--user-agent或者-A选项:
curl URL --user-agent &Mozilla/5.0&
curl URL -A &Mozilla/5.0&
其他HTTP头部信息也可以使用curl来发送,使用-H&头部信息& 传递多个头部信息,例如:
curl -H &Host:man.linuxde.net& -H &-language:zh-cn& URL
curl的带宽控制和下载配额
使用--limit-rate限制curl的下载速度:
curl URL --limit-rate 50k
命令中用k(千字节)和m(兆字节)指定下载速度限制。
使用--max-filesize指定可下载的最大文件大小:
curl URL --max-filesize bytes
如果文件大小超出限制,命令则返回一个非0退出码,如果命令正常则返回0。
用curl进行认证
使用curl选项&-u&可以完成HTTP或者FTP的认证,可以指定密码,也可以不指定密码在后续操作中输入密码:
curl -u user: http://man.linuxde.net
curl -u user http://man.linuxde.net
只打印响应头部信息
通过-I或者-head可以只打印出HTTP头部信息:
[root@localhost text]# curl -I http://man.linuxde.net
HTTP/1.1 200 OK
Server: nginx/1.2.5
: Mon, 10 Dec :34 GMT
Content-Type: text/ charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Pingback: http://man.linuxde.net/xmlrpc.
最近更新的命令
在Linux命令大全(man.linuxde.net)可以查询您所需要的Linux命令教程和相关实例。如果您觉得本站内容对您有所帮助,请推荐给更多需要帮助的人。下次自动登录
现在的位置:
& 综合 & 正文
curl 代理使用
什么是代理?Merrian-Webster的解释是:一个通过验证的用户扮演另一个用户。今天,代理已经被广泛的使用。许多公司提供网络代理服务器,允许员工的网络客户端访问、下载文件。代理服务器处理这些用户的请求。
libcurl支持SOCKS和HTTP代理。使用代理,libcurl会把用户输入的URL提交给代理服务器,而不是直接根据URL去访问远程资源。
当前版本的libcurl并不支持SOCKS代理的所有功能。
对于HTTP代理来说,即使请求的URL不是一个合法的HTTP URL(比方你提供了一个ftp的url),它仍然会先被提交到HTTP代理。
CURLOPT_PROXY属性用于设置libcurl使用的代理服务器地址:
curl_easy_setopt(easy_handle, CURLOPT_PROXY, ":8080");
可以把主机名与端口号分开设置:
curl_easy_setopt(easy_handle, CURLOPT_PROXY, "");
curl_easy_setopt(easy_handle, CURLOPT_PROXYPORT, "8080"); // 端口号是用字符串还是整数??
有些代理服务器要求用户通过验证之后才允许接受其请求,此时应该先提供验证信息:
curl_easy_setopt(easy_handle, CURLOPT_PROXYUSERPWD, "user:password");
还要告诉libcurl使用的代理类型(如果没有提供,libcurl会认为是HTTP代理):
curl_easy_setopt(easy_handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
对于有些协议,libcurl会自动检测并使用一些环境变量,并根据这些环境变量来确定要使用的代理服务器。这些环境变量的名称格式一般是"[protocol]_proxy"(注意小写)。例如输入一个HTTP的URL,那么名称为"http_proxy"的环境变量就会被检测是否存在,如果存在,libcurl会使用该环境变量指定的代理。相同的规则也适用于FTP。
这些环境变量的值的格式必须是这样的:"[protocol://][user:password@]machine[:port]"。libcurl会忽略掉[protocol://],如果没有提供端口号,libcurl使用该协议的默认端口。
有两个比较特殊的环境变量:'all_proxy'与'no_proxy'。如果一个URL所对应的协议,它的环境变量没有设置,那么'all_proxy'指定的代理将被使用。'no_proxy'则指定了一个不应被使用的代理主机的列表。例如:no_proxy的值是'192.168.1.10',即使存在http_proxy,它的值也是'192.168.1.10','192.168.1.10'也不会被作为代理。no_proxy=”*”表示不允许使用任何代理。
显式地将CURLOPT_PROXY属性设置为空,可以禁止libcurl检查并使用环境变量来使用代理。
SSL为点到点通信提供安全保障。它包含一些强壮的加密措施和其他安全检测,这使得上面讲到的代理方式不适用于SSL。除非代理服务器提供专用通道,对进出该代理服务器的数据不作任何检测或禁止。通过HTTP代理服务器打开SSL连接,意味着代理服务器要直接连接到目标主机的指定端口。因为代理服务器对在专用通道上传输的数据的类型毫无所知,所以它往往会使某些机制失效,如缓存机制。许多组织只允许在443端口上创建这种类型的数据通道。
代理通道(Tunneling Through Proxy)
正如上面讲到的,要使SSL工作必须在代理服务器创建专用数据通道,通常专用通道只被限制应用于HTTPS。通过HTTP代理在应用与目标之间创建一个专用数据通道,应该预防在该专有通道上执行非HTTP的操作,如进行FTP上传或执行FTP命令。代理服务器管理员应该禁止非法的操作。
通过CURLOPT_HTTPPROXYTUNNEL属性来告诉libcurl使用代理通道:
curl_easy_setopt(easy_handle, CURLOPT_HTTPPROXYTUNNEL, 1L);
有时候你想通过代理通道执行平常的HTTP操作,而实际上却可能使你不经过代理服务器而直接与远程主机进行交互。libcurl不会代替这种新引入的行为。
自动配置代理
许多浏览器支持自动配置代理,例如NetScape。libcurl并不支持这些。
持久化的好处(Persistence Is The Way to Happiness)
当需要发送多次请求时,应该重复使用easy handle。
每次执行完curl_easy_perform,licurl会继续保持与服务器的连接。接下来的请求可以使用这个连接而不必创建新的连接(如果目标主机是同一个的话)。这样可以减少网络开销。
即使连接被释放了,libcurl也会缓存这些连接的会话信息,这样下次再连接到目标主机上时,就可以使用这些信息,从而减少重新连接所需的时间。
FTP连接可能会被保存较长的时间。因为客户端要与FTP服务器进行频繁的命令交互。对于有访问人数上限的FTP服务器,保持一个长连接,可以使你不需要排除等待,就直接可以与FTP服务器通信。
libcurl会缓存DNS的解析结果。
在今后的libcurl版本中,还会添加一些特性来提高数据通信的效率。
每个easy handle都会保存最近使用的几个连接,以备重用。默认是5个。可以通过CURLOPT_MAXCONNECTS属性来设置保存连接的数量。
如果你不想重用连接,将CURLOPT_FRESH_CONNECT属性设置为1。这样每次提交请求时,libcurl都会先关闭以前创建的连接,然后重新创建一个新的连接。也可以将CURLOPT_FORBID_REUSE设置为1,这样每次执行完请求,连接就会马上关闭。
libcurl使用的HTTP消息头
当使用libcurl发送http请求时,它会自动添加一些http头。我们可以通过CURLOPT_HTTPHEADER属性手动替换、添加或删除相应的HTTP消息头。
http1.1(大部分http1.0)版本都要求客户端请求提供这个信息头。
"no-cache"。表示不要缓冲数据。
"*/*"。表示允许接收任何类型的数据。
以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");
修改消息头
HTTP协议提供了消息头,请求消息头用于告诉服务器如何处理请求;响应消息头则告诉浏览器如何处理接收到的数据。在libcurl中,你可以自由的添加这些消息头:
struct curl_slist *headers=NULL; /* init to NULL is important */
headers = curl_slist_append(headers, "Hey-server-hey: how are you?");
headers = curl_slist_append(headers, "X-silly-content: yes");
/* pass our list of custom made headers */
curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(easyhandle); /* transfer http */
curl_slist_free_all(headers); /* free the header list */
对于已经存在的消息头,可以重新设置它的值:
headers = curl_slist_append(headers, "Accept: Agent-007");
headers = curl_slist_append(headers, "Host: munged.host.line");
删除消息头
对于一个已经存在的消息头,设置它的内容为空,libcurl在发送请求时就不会同时提交该消息头:
headers = curl_slist_append(headers, "Accept:");
强制分块传输(Enforcing chunked transfer-encoding)
(这段文字理解可能有误码)以非GET的方式提交HTTP请求时,如果设置了自定义的消息头”Transfer-Encoding:chunked”,libcurl会分块提交数据,即使要上传的数据量已经知道。在上传数据大小未知的情况下,libcurl自动采用分块上传数据。(译者注:非GET方式提交请求,提交的数据量往往比较大。)
每一次http请求,都包含一个表示当前使用http版本的消息头。libcurl默认使用HTTP 1.1。可以通过CURLOPT_HTTP_VERSION属性来设置具体的版本号:
curl_easy_setopt(easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
FTP自定义命令
并不是所以的协议都像HTTP那样,通过消息头来告诉服务器如何处理请求。对于FTP,你就要使用另外的方式来处理。
发送自定义的命令到ftp服务器,意味着你发送的命令必须是能被ftp服务器理解的命令(FTP协议中定义的命令,参考rfc959)。
下面是一个简单的例子,在文件传输操作操作之前删除指定文件:
headers = curl_slist_append(headers, "DELE file-to-remove");
/* pass the list of custom commands to the handle */
curl_easy_setopt(easyhandle, CURLOPT_QUOTE, headers);
// curl_easy_setopt(easyhandle, CURLOPT_POSTQUOTE, headers); // 在数据传输之后操行删除操作curl_easy_perform(easyhandle); /* transfer ftp data! */
curl_slist_free_all(headers); /* free the header list */
FTP服务器执行命令的顺序,同这些命令被添加到列表中顺序是一致的。发往服务器的命令列表中,只要有一个命令执行失败,ftp服务器就会返回一个错误,此时libcurl将直接返回CURLE_QUOTE_ERROR,不再执行剩余的FTP命令。
将CURLOPT_HEADER设置为1,libcurl获取目标文件的信息,并以HTTP消息头的样式来输出消息头。
FTP自定义CUSTOMREQUEST
使用CURLOPT_CUSTOMREQUEST属性,可以向FTP服务器发送命令。"NLST"是ftp默认的列出文件列表的命令。 下面的代码用于列出FTP服务器上的文件列表:
int main(int argc, char **argv)
curl_global_init(CURL_GLOBAL_WIN32);
CURL *easy_handle = curl_easy_init();
curl_easy_setopt(easy_handle, CURLOPT_URL, ", CURLOPT_CUSTOMREQUEST, "NLST"); curl_easy_perform(easy_handle);
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
} Cookies Without Chocolate Chips
cookie是一个键值对的集合,HTTP服务器发给客户端的cookie,客户端提交请求的时候,也会将cookie发送到服务器。服务器可以根据cookie来跟踪用户的会话信息。cookie有过期时间,超时后cookie就会失效。cookie有域名和路径限制,cookie只能发给指定域名和路径的HTTP服务器。
cookie以消息头”Set-Cookie”的形式从HTTP服务器发送到客户端;客户端发以消息头”Cookie”的形式将Cookie提交到HTTP服务器。为了对这些东西有个直观的概念,下图是FireFox中,使用Firebug跟踪到的cookie消息头:
在libcurl中,可以通过CURLOPT_COOKIE属性来设置发往服务器的cookie:
curl_easy_setopt(easy_handle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
下面的例子演示了如何使用libcurl发送cookie信息给HTTP服务器,代码非常的简单:
int main(int argc, char **argv)
curl_global_init(CURL_GLOBAL_WIN32);
CURL *easy_handle = curl_easy_init();
curl_easy_setopt(easy_handle, CURLOPT_URL, , CURLOPT_COOKIE, "name=JG address=HangZhou");
curl_easy_perform(easy_handle);
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
下图是在ASP.NET Web服务器上调试时跟踪到的Cookie数据:
在实在的应用场景中,你可能需要保存服务器发送给你的cookie,并在接下来的请求中,把这些cookie一并发往服务器。所以,可以把上次从服务器收到的所有响应头信息保存到文本文件中,当下次需要向服务器发送请求时,通过CURLOPT_COOKIEFILE属性告诉libcurl从该文件中读取cookie信息。
设置CURLOPT_COOKIEFILE属性意味着激活libcurl的cookie parser。在cookie parser被激活之前,libcurl忽略所以之前接收到的cookie信息。cookie parser被激活之后,cookie信息将被保存内存中,在接下来的请求中,libcurl会自动将这些cookie信息添加到消息头里,你的应用程序不需要做任何事件。大多数情况下,这已经足够了。需要注意的是,通过CURLOPT_COOKIEFILE属性来激活cookie parser,给CURLOPT_COOKIEFILE属性设置的一个保存cookie信息的文本文件路径,可能并不需要在磁盘上物理存在。
如果你需要使用NetScape或者FireFox浏览器的cookie文件,你只要用这些浏览器的cookie文件的路径来初始化CURLOPT_COOKIEFILE属性,libcurl会自动分析cookie文件,并在接下来的请求过程中使用这些cookie信息。
libcurl甚至能够把接收到的cookie信息保存成能被Netscape/Mozilla的浏览器所识别的cookie文件。通过把这些称为cookie-jar。通过设置CURLOPT_COOKIEJAR选项,在调用curl_easy_cleanup释放easy handle的时候,所有的这些cookie信息都会保存到cookie-jar文件中。这就使得cookie信息能在不同的easy handle甚至在浏览器之间实现共享。
FTP Peculiarities We Need
在使用FTP协议进行数据传输的时候,需要创建两个连接。第一个连接用于传输控制命令,另一个连接用于传输数据。(关于FTP的通信过程,请参考这篇:)。 FTP通信需要创建两个连接这个事实往往被很多人忽略。根据第二个连接的发起方是谁,可以分为主动模式与被动模式。libcurl对此都提供了支持。libcurl默认使用被动模式,因为被动模式可以方便的穿透防火墙,NAT等问题。在被动模式下,libcurl要求ftp服务器打开一个新的端口监听,然后libcurl连接该端口用于数据传输。如果使用主动模式,程序必须告诉FTP服务器你监听的IP与端口,通过设置CURLOPT_FTPPORT属性来完成。
Headers Equal Fun
(这段文字我理解的很模糊,请读者参考原文)有些协议提供独立于正常数据的 消息头、meta-data。正常的数据流里通常不包括 信息头和元数据。可以将CURLOPT_HEADER设置为1,使信息头、元数据也能出现在数据流中。libcurl的强大之处在于,它能够从数据流中解析出消息头,….
Post Transfer Information
[ curl_easy_getinfo ]
请参考原文,此处略。
使用multi interface同时进行多项传输
上面介绍的easy interface以同步的方式进行数据传输,curl_easy_perform会一直阻塞到数据传输完毕后返回,且一次操作只能发送一次请求,如果要同时发送多个请求,必须使用多线程。
而multi interface以一种简单的、非阻塞的方式进行传输,它允许在一个线程中,同时提交多个相同类型的请求。 在使用multi interface之前,你应该掌握easy interface的基本使用。因为multi interface是建立在easy interface基础之上的,它只是简单的将多个easy handler添加到一个multi stack,而后同时传输而已。
使用multi interface很简单,首先使用curl_multi_init()函数创建一个multi handler,然后使用curl_easy_init()创建一个或多个easy handler,并按照上面几章介绍的接口正常的设置相关的属性,然后通过curl_multi_add_handler将这些easy handler添加到multi handler,最后调用curl_multi_perform进行数据传输。
curl_multi_perform是异步的、非阻塞的函数。如果它返回CURLM_CALL_MULTI_PERFORM,表示数据通信正在进行。
通过select()来操作multi interface将会使工作变得简单(译者注:其实每个easy handler在低层就是一个socket,通过select()来管理这些socket,在有数据可读/可写/异常的时候,通知应用程序)。在调用select()函数之前,应该使用curl_multi_fdset来初始化fd_set变量。
select()函数返回时,说明受管理的低层socket可以操作相应的操作(接收数据或发送数据,或者连接已经断开),此时应该马上调用curl_multi_perform,libcurl将会执行相应操作。使用select()时,应该设置一个较短的超时时间。在调用select()之前,造成不要忘记通过curl_multi_fdset来初始化fd_set,因为每次操作,fd_set中的文件描述符可能都不一样。
如果你想中止multi stack中某一个easy handle的数据通信,可以调用curl_multi_remove_handle函数将其从multi stack中取出。千万另忘记释放掉easy handle(通过curl_easy_cleanup()函数)。
当multi stack中的一个eash handle完成数据传输的时候,同时运行的传输任务数量就会减少一个。当数量降到0的时候,说明所有的数据传输已经完成。
curl_multi_info_read用于获取当前已经完成的传输任务信息,它返回每一个easy handle的CURLcode状态码。可以根据这个状态码来判断每个easy handle传输是否成功。
下面的例子,演示了如何使用multi interface进行网页抓取:
int main(int argc, char **argv)
curl_global_init(CURL_GLOBAL_WIN32);
CURLM *multi_handle = NULL;
CURL *easy_handle1 = NULL;
CURL *easy_handle2 = NULL;
extern size_t save_sina_page(void *buffer, size_t size, size_t count, void *user_p);
extern size_t save_sohu_page(void *buffer, size_t size, size_t count, void *user_p);
FILE *fp_sina = fopen("sina.html", "ab+");
FILE *fp_sohu = fopen("sohu.html", "ab+");
multi_handle = curl_multi_init();
// 设置easy handle
easy_handle1 = curl_easy_init();
curl_easy_setopt(easy_handle1, CURLOPT_URL, "");
curl_easy_setopt(easy_handle1, CURLOPT_WRITEFUNCTION, &save_sina_page);
curl_easy_setopt(easy_handle1, CURLOPT_WRITEDATA, fp_sina);
easy_handle2 = curl_easy_init();
curl_easy_setopt(easy_handle2, CURLOPT_URL, "");
curl_easy_setopt(easy_handle2, CURLOPT_WRITEFUNCTION, &save_sohu_page);
curl_easy_setopt(easy_handle2, CURLOPT_WRITEDATA, fp_sohu);
// 添加到multi stack
curl_multi_add_handle(multi_handle, easy_handle1);
curl_multi_add_handle(multi_handle, easy_handle2);
int running_handle_
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &running_handle_count))
cout && running_handle_count &&
while (running_handle_count)
tv.tv_sec = 1;
tv.tv_usec = 0;
fd_set fd_
fd_set fd_
fd_set fd_
FD_ZERO(&fd_read);
FD_ZERO(&fd_write);
FD_ZERO(&fd_except);
curl_multi_fdset(multi_handle, &fd_read, &fd_write, &fd_except, &max_fd);
int return_code = select(max_fd + 1, &fd_read, &fd_write, &fd_except, &tv);
if (SOCKET_ERROR == return_code)
cerr && "select error." &&
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &running_handle_count))
cout && running_handle_count &&
// 释放资源
fclose(fp_sina);
fclose(fp_sohu);
curl_easy_cleanup(easy_handle1);
curl_easy_cleanup(easy_handle2);
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
size_t save_sina_page(void *buffer, size_t size, size_t count, void *user_p)
return fwrite(buffer, size, count, (FILE *)user_p);
size_t save_sohu_page(void *buffer, size_t size, size_t count, void *user_p)
return fwrite(buffer, size, count, (FILE *)user_p);
} SSL, 证书,其他技巧
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]
在easy handler之间共享数据
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 curl 代理ip 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信