如何做网站模版,南宁做网约车怎么样,wordpress手机端边侧航栏,做网站接专线费用网络篇#xff0c;书上672~674页#xff0c;带进度的FTP下载的的实例程序#xff0c;写了两遍#xff0c;才写成功#xff0c;而且第二遍写的时候#xff0c;对易错的地方有所感悟#xff0c;写篇心得记下来。 首先上代码#xff1a;
#include curl/curl.h
#i…网络篇书上672~674页带进度的FTP下载的的实例程序写了两遍才写成功而且第二遍写的时候对易错的地方有所感悟写篇心得记下来。 首先上代码
#include curl/curl.h
#include iostream
#include fstream
#include sstream //stringstreamusing namespace std;int to_size(char* data, size_t size, size_t nmemb, void* userdata)
{int result_code 0;string s(data, size*nmemb);stringstream ss(s);ss result_code;if(!ss.bad() result_code 213){int* pcode static_cast int* (userdata);ss *pcode;}return nmemb*size;
}int to_stream(char* data, size_t size, size_t nmemb, void* userdata)
{ostream os *static_cast ostream* (userdata);std::string line(data, size*nmemb);os line;return size*nmemb;
}//当需要通知进度时回调
int down_progress(void*, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{if(dltotal 0)return 0;int count (dlnow * 1.0 / dltotal) * 50; //确定需要画多少个等号cout (dlnow * 100 / dltotal) %; //确定百分比for(int i 0; i count; i){cout ;}cout endl;return 0;
}//取FTP服务器指定文件的大小
int get_server_file_size(string const server_url, string const username, string const password, string const pathfile)
{CURL* handle curl_easy_init();curl_easy_setopt(handle, CURLOPT_URL, server_url.c_str());//username和password也需要C形式的字符串curl_easy_setopt(handle, CURLOPT_USERNAME, username.c_str());curl_easy_setopt(handle, CURLOPT_PASSWORD, password.c_str());string cmd SIZE pathfile; //SIZE后面要有个分号curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, cmd.c_str());int filesize 0;curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, to_size);curl_easy_setopt(handle, CURLOPT_HEADERDATA, static_cast void* (filesize));curl_easy_perform(handle);cout filesize filesize endl;curl_easy_cleanup(handle);return filesize;
}int main()
{curl_global_init(CURL_GLOBAL_DEFAULT);CURL* handle curl_easy_init();ofstream ofs(a.zip, ios_base::out | ios_base::binary);if(!ofs){cerr 无法打开本地文件a.zip。 endl;return -1;}string server_url ftp://127.0.0.1:21/;string pathfile fengjie/meili/2.zip;string username d2school;string password 123456;//取服务端指定文件大小size_t file_size get_server_file_size(server_url, username, password, pathfile);//告诉libcurl待下载文件的总大小curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, static_cast curl_off_t (file_size));//开启进度通知curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);curl_easy_setopt(handle, CURLOPT_XFERINFOFUNCTION, down_progress);//设置如何处理下载的数据string url server_url pathfile;curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
// //username和password也需要C形式的字符串curl_easy_setopt(handle, CURLOPT_USERNAME, username.c_str());curl_easy_setopt(handle, CURLOPT_PASSWORD, password.c_str());//本次下载采用直接定位到文件的方式类似于http协议的下载不需要使用ftp命令 RETR 文件名curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, to_stream);curl_easy_setopt(handle, CURLOPT_WRITEDATA, static_cast void* (ofs));curl_easy_perform(handle);//启动下载ofs.close();//关闭流curl_easy_cleanup(handle);curl_global_cleanup();return 0;
}易错点分析
65行要注意SIZE后面要有个分号 62,63, 107108行要注意username和password不要忘了使用c_str()转化成“C”形式的字符串 110行本次下载采用直接定位到文件的方式类似于http协议的下载不需要使用ftp命令 RETR 文件名 116行关闭流这个容易遗忘。不过这一行即使遗忘了应该也不会有问题因为ofs是栈变量会自动回收内存。 写的过程要注意不要一口气把整个程序写完否则出了错会花费老大劲去寻找错误。 首先main函数中写到96行要测试一下看看能不能得到文件的大小如果不能得到则停下来排查错误。把错误解决完再继续往下写。
接下来先写104-112行的内容看看能否把文件下载下来若不能则同样排查错误。把错误解决完再继续写98-101行的内容把下载进度通知加上。