各位亲 有时间可以去看看我的 “金骏家居淘宝店” http://jinjun1688.taobao.com/shop/view_shop.htm?tracelog=twddp 买时说明在我的博客看到有优惠哦
还有意外礼品赠送 真正的程序员淘宝店
Libcurl简介:
Libcurl为一个免费开源的,客户端url传输库,支持FTP,FTPS,TFTP,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP,跨平台,支持Windows,Unix,Linux等,线程安全,支持Ipv6。并且易于使用。
多线程问题
首先一个基本原则就是:绝对不应该在线程之间共享同一个libcurlhandle,不管是easy handle还是multihandle(将在下文中介绍)。一个线程每次只能使用一个handle。
上传数据到远程站点
libcurl提供无关的方式进行数据传输。上传一个文件到FTP服务器:
1.创建easy handle或者重用之前创建的easyhandle。
2.设置CURLOPT_URL 属性。
3.编写返回回调函数。在执行上传的时候,libcurl通过回调函数读取要上传的数据。(如果是远程服务器下载数据,可以通过回调来保存接手的数据。)回调函数的原型如下:
size_tfunction(char *bufptr,size_t size,size_t nitems ,void *userp);
注:butptr指针表示缓冲区,用于保存要上传的数据,size*nitems 是缓冲区数据的长度,userp是一个用户自定义指针,libcurl不对该指针作任何操作,它只是简单的传递该指针,可以使用该指针再应用程序与libcurl之间传递信息。
4. 注册回调函数,设置自定义指针。语法如下:
// 注册回调函数
curl_easy_setopt(easy_handle,CURLOPT_READFUNCTION, read_function);
// 设置自定义指针
curl_easy_setopt(easy_handle,CURLOPT_READDATA, &filedata);
5.告诉libcurl,执行的是上传操作。
curl_easy_setopt(easy_handle,CURLOPT_UPLOAD, 1L);
有些协议在没有预先知道上传文件大小的情况下,可能无法正确判断上传是否结束,所以最好预先使用CURLOPT_INFILESIZE_LARGE属性:告诉它要上传文件的大小:
curl_easy_setopt(easy_handle,CURLOPT_INFILESIZE_LARGE, file_size);
6.调用curl_easy_perform。
接下来,libcurl将会完成剩下的所有工作。在上传文件过程中,libcurl会不断调用先前设置的回调函数,用于将要上传的数据读入到缓冲区,并执行上传。
例子:
//读取数据的回调
static size_t OnWriteData(void*buffer,size_t size,
size_t nmemb,void* lpVoid)
{
std::string* str =dynamic_cast<std::string*>((std::string *)lpVoid);
if( NULL == str || NULL ==buffer )
{
return -1;
}
char* pData = (char*)buffer;
str->append(pData, size * nmemb);
return nmemb;
}
post上传
SimpleSyncPost(const std::string& aUrl,
const std::string& aPostData,
std::string &aResponseData)
{
CURL *curl = curl_easy_init();
CURLcode res;
if (!curl) {
return CURLE_FAILED_INIT;
}
std::string jsonResponse;
curl_easy_setopt(curl, CURLOPT_URL, aUrl.c_str());
//这个 URL是一个以 '\0' 结尾的字符串或参数指针 这个选项是唯一一个必须在 curl_easy_perform()调用之前就要设置的选项。
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,aPostData.c_str());//传递一个作为HTTP “POST”操作的所有数据的字符串
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); //回调函数 用此来保存接收到的数据点大小
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&aResponseData);//函数会将接收到的数据自动的写到这个 FILE指针所指向的文件流中
curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1); //curl需要进行毫秒超时使用
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, VAN_CONNECT_TIMEOUT);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, VAN_POST_TIMEOUT); //设置一个长整形数,作为最大延续多少秒
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
注:如果需要传输一些二进制数据到FTP服务器,实际提交一个字符串,字符串遇到/0就结束了。所以要在上传二进制数据的时候,必须要明确的告诉libcurl要提交的数据的长度,再上传二进制数据的时候,还应该设置提交的content-Type头信息。
//添加提交数据长度
curl_easy_setopt(easy_handle,CURLOPT_POSTFIELDSIZE,sizeof(data));
//设置头信息
http_headers= curl_slist_append(http_headers, "Content-Type:text/xml");
curl_easy_setopt(easy_handle,CURLOPT_HTTPHEADER, http_headers);
Get下载
SimpleSyncGet(const std::string& aUrl, std::string &aResponseData)
{
CURL *curl = curl_easy_init();
CURLcode res;
if (!curl) {
return CURLE_FAILED_INIT;
}
curl_easy_setopt(curl,CURLOPT_URL, aUrl.c_str());
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl,CURLOPT_WRITEDATA, (void *)&aResponseData);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return res;
}
在easy handle上设置的属性都将被保存,即使执行完curl_easy_perform之后,这些属性值仍然存在。通过将CURLOPT_HTTPGET设为1可以使easy handle回到最原始的状态:
curl_easy_setopt(easy_handle,CURLOPT_HTTPGET, 1L);
curl_easy_setopt–curl库的参数分析
函数原型: #include <curl/curl.h> CURLcodecurl_easy_setopt(CURL *handle, CURLoption option, parameter);
说明:此函数用来告诉 libcurl 执行什么样的动作。该函数有 3 个参数(该函数的可设置选项非常之多):第 1 个参数 handle 是由 curl_easy_init() 返回的句柄;第 2 个参数是可以设置的选项(CURLoption);第 3 个参数是与第 2 个选项相关联的参数,这个参数可以是 long 型,也可以是一个函数指针(function pointer),还可以是一个对象的指针 (object pointer),或者是一个 curl_off_t 类型,这些参数类型必须由选项值(CURLoption)来确定。
网络选项(NETWORK OPTIONS):
1) CURLOPT_URL:这是你想用PHP取回的URL地址。你也可以在用curl_init()函数初始化时设置这个选项。
2) CURLOPT_POSTFIELDS:传递一个作为HTTP“POST”操作的所有数据的字符串
3) CURLOPT_POSTFIELDSIZE 该选项要求第 3 个参数 parameter 是一个 void * 指针,它指向一个向 HTTP 服务器 POST 出去的一段数据,这段数据要根据服务器的具体要求填写。
4) CURLOPT_WRITEFUNCTION 使用该选项时,要求第 3 个参数中的回调函数必须是下面的函数原型:
size_t function( char *ptr, size_t size, size_t nmemb, void *userdata);
5) CURLOPT_WRITEDATA 使用该选项时,第 3 个参数作为用户数据的指针而传递到使用 CURLOPT_WRITEFUNCTION 选项时指定的回调函数中(第 4 个参数)。如果不想用回调函数而保存数据,那么可以使用 CURLOPT_WRITEDATA 选项,使用该选项时,函数的第 3 个参数必须是个 FILE 指针,函数会将接收到的数据自动的写到这个 FILE 指针所指向的文件流中。
6) CURLOPT_HEADER 使用该选项时,第 3 个参数设置为 1,那么会通知 curl 库在输出时要同时包含 "头部“ 和 "主题内容" 两个部分。
7) CURLOPT_WRITEHEADER 和 CURLOPT_HEADERDATA 这两个选项是同一种意思。它们和第 5 条中的 CURLOPT_WRITEDATA 选项功能一样,表示在接收到头部信息并调用回调函数时,给回调函数传递第 4 个参数。
8) CURLOPT_RANGE: 传递一个你想指定的范围。它应该是”X-Y”格式,X或Y是被除外的。HTTP传送同样支持几个间隔,用逗句来分隔(X-Y,N-M)。
9) CURLOPT_POSTFIELDS: 传递一个作为HTTP“POST”操作的所有数据的字符串。