最近的学习文件上传和下载用到了libcurl库,研究了一段时间现将心得写下也算是给后来者一个参考。
最好的学习资料当然是官网的介绍和例子http://curl.haxx.se/libcurl/c/
正常情况下用easy模式就可以了。
主要就是curl_easy_init() curl_easy_setopt curl_easy_perform其中最重要的就是curl_easy_setopt了
可以自己写个类封装下,主要是上传和下载
</pre><pre name="code" class="cpp">
//第一个参数是有效的url地址,第二个是要上传的本地文件夹,第三个是密码,第四个是最大上传速度,第五个是超时时间
<pre name="code" class="cpp">int MYFTPClient::UploadFile(const char * strURL,const char * strFile,const char * password ,int speed ,long timeout,bool IsCurrent)
{
CURL *curlhandle = curl_easy_init();
if(NULL == curlhandle)
{
cout <<"初始化失败 "<< endl;
return -1;
}
CURLcode res = CURLE_GOT_NOTHING;
mstrFile = strFile;
curl_easy_setopt(curlhandle,CURLOPT_URL,strURL);
curl_easy_setopt(curlhandle,CURLOPT_USERPWD,password);
curl_easy_setopt(curlhandle,CURLOPT_UPLOAD,1L);
curl_easy_setopt(curlhandle,CURLOPT_WRITEFUNCTION,NULL);
// if(timeout)
// curl_easy_setopt(curlhandle,CURLOPT_FTP_RESPONSE_TIMEOUT,timeout); //换成CURLOPT_LOW_SPEED_LIMIT和CURLOPT_LOW_SRPPD_TIME 来替代
curl_easy_setopt(curlhandle,CURLOPT_READFUNCTION,readfunc);
curl_easy_setopt(curlhandle,CURLOPT_READDATA,this);
curl_easy_setopt(curlhandle,CURLOPT_FTP_CREATE_MISSING_DIRS,1L);
if(! IsCurrent) //不是实时的才需要进行断点续传
{
if(GetRemoteFileSize(strURL,password) != -1) //断点续传先判断是否上传
{
if(GetRemoteFileSize(strURL,password) != GetlocalFileSize(strFile)) //不相等就是没有完全上传成功
{
curl_easy_setopt(curlhandle,CURLOPT_RESUME_FROM_LARGE,GetRemoteFileSize(strURL,password)); //断点续传
UploadSize = GetRemoteFileSize(strURL,password);
}
}
else
{
UploadSize = 0;
curl_easy_setopt(curlhandle,CURLOPT_RESUME_FROM_LARGE,UploadSize);
}
}
curl_easy_setopt(curlhandle,CURLOPT_INFILESIZE_LARGE,GetlocalFileSize(strFile));//需要上传文件大小
curl_easy_setopt(curlhandle,CURLOPT_VERBOSE,1L);
curl_easy_setopt(curlhandle,CURLOPT_NOPROGRESS,0L);
curl_easy_setopt(curlhandle,CURLOPT_XFERINFOFUNCTION,onprogress);//进度回调函数
curl_easy_setopt(curlhandle,CURLOPT_XFERINFODATA,this);
//curl_easy_setopt(curlhandle,CURLOPT_DEBUGDATA,this);
//curl_easy_setopt(curlhandle,CURLOPT_DEBUGFUNCTION,mytrace);
curl_easy_setopt(curlhandle,CURLOPT_NOSIGNAL,1L); //多线程需要
if(timeout)
{
curl_easy_setopt(curlhandle,CURLOPT_LOW_SPEED_LIMIT,100L);
curl_easy_setopt(curlhandle,CURLOPT_LOW_SPEED_TIME,timeout);
}
if(speed)
curl_easy_setopt(curlhandle,CURLOPT_MAX_SEND_SPEED_LARGE,static_cast<INT64>(speed*1024));//上传速度限制单位为KB
res = curl_easy_perform(curlhandle);
curl_easy_cleanup(curlhandle);
mstrFile.clear();
if(res != CURLE_OK)
{
cout << curl_easy_strerror(res);
return -1;
}
//remove(strFile);
/*WCHAR wname[256];
memset(wname,0,sizeof(wname));
MultiByteToWideChar(CP_ACP,0,strFile,strlen(strFile)+1,wname,sizeof(wname)/sizeof(wname[0])); //char * 到 LPCWSTR的转换
DeleteFile(wname);*/
return 0;
}
下载也也差不多。主要介绍一下各种参数的设置吧。比较重要的是
curl_easy_setopt(curlhandle,CURLOPT_RESUME_FROM_LARGE,GetRemoteFileSize(strURL,password)); 设置断点续传的,
也可以用curl_easy_setopt(curlhandle,CURLOPT_RANGE,srange.c_str());最后一个参数是“x-y"类型从多少道多少
还有一个就是限速设置要转换成int64不然会没有效果。官方文档建议用<pre name="code" class="cpp" style="font-size:18px;">curl_easy_setopt(curlhandle,CURLOPT_LOW_SPEED_LIMIT,100L);
curl_easy_setopt(curlhandle,CURLOPT_LOW_SPEED_TIME,timeout);这两个替代CURLOPT_TIMEOUT了。表示在规定的时间内如果速度小于指定CURLOPT_LOW_SPEED_LIMIT就会返回从而防止阻塞的问题。