最近的学习文件上传和下载用到了libcurl库,研究了一段时间现将心得写下也算是给后来者一个参考。
最好的学习资料当然是官网的介绍和例子http://curl.haxx.se/libcurl/c/
正常情况下用easy模式就可以了。
主要就是curl_easy_init() curl_easy_setopt curl_easy_perform其中最重要的就是curl_easy_setopt了
可以自己写个类封装下,主要是上传和下载
//第一个参数是有效的url地址,第二个是要上传的本地文件夹,第三个是密码,第四个是最大上传速度,第五个是超时时间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(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不然会没有效果。官方文档建议用
curl_easy_setopt(curlhandle,CURLOPT_LOW_SPEED_LIMIT,100L); curl_easy_setopt(curlhandle,CURLOPT_LOW_SPEED_TIME,timeout);这两个替代CURLOPT_TIMEOUT了。表示在规定的时间内如果速度小于指定CURLOPT_LOW_SPEED_LIMIT就会返回从而防止阻塞的问题。