使用libcurl显示下载进度
2016-12-25 23:24
337 查看
(1)s_get_download_file_length函数获取目标文件大小。
(2)进度条处理函数CURLOPT_PROGRESSFUNCTION,注意设置的回调函数不要忘记了正常情况下return 0;否则将会导致回调异常。
(2)进度条处理函数CURLOPT_PROGRESSFUNCTION,注意设置的回调函数不要忘记了正常情况下return 0;否则将会导致回调异常。
/********************* ftp_down_load.c **********************/ #include <stdio.h> #include <stdlib.h> #include <string.h> //#include <curl/curl.h> #include <curl/curl.h> #define UserNameMaxLen 100 #define PasswordMaxLen 50 #define UrlMaxLen 1024 #define DesFileName "/share/binxu.rmvb" #define FtpUrl "ftp://192.168.1.102/binxu.rmvb" typedef struct ftp_init_param_s { int dumy; }ftp_init_param_t; typedef struct ftp_connect_param_s { char chUserName[UserNameMaxLen]; char chPassword[PasswordMaxLen]; char chUrl[UrlMaxLen]; char chUserPwd[UserNameMaxLen+PasswordMaxLen]; }ftp_connect_param_t; typedef struct ftp_file_s { const char *pchFilename; FILE *stream; double nFileLength; double nCount; unsigned int nPersent; }ftp_file_t; void main_ftp_download_test(); int ftp_download(ftp_connect_param_t * pstuFtpConnectParam,ftp_file_t *pstuFtpFile); int ftp_init(void *param); int s_curl_init(); int s_curl_term(); double s_get_download_file_length(ftp_connect_param_t * pstuFtpConnectParam); void set_ftp_file(ftp_file_t *pstuFtpFile, char *pchFileName); void set_ftp_connect_param(ftp_connect_param_t * pstuFtpConnectParam); int main() { main_ftp_download_test(); return 0; } void main_ftp_download_test() { ftp_init_param_t pstuInitParam; ftp_file_t stuFtpFile; ftp_connect_param_t stuFtpConnectParam; memset(&pstuInitParam, 0, sizeof(ftp_init_param_t)); if(0 != ftp_init(&pstuInitParam)) { printf("\n ftp_init error \n"); return; }; memset(&stuFtpConnectParam, 0, sizeof(ftp_connect_param_t)); set_ftp_connect_param(&stuFtpConnectParam); memset(&stuFtpFile, 0, sizeof(ftp_file_t)); set_ftp_file(&stuFtpFile, DesFileName); stuFtpFile.nFileLength = s_get_download_file_length(&stuFtpConnectParam); if(-1 == stuFtpFile.nFileLength) { printf("\n s_get_download_file_length error \n"); return; } printf("\n##### file len = %lf #####\n",stuFtpFile.nFileLength); //int ftp_download(ftp_connect_param_t * pstuFtpConnectParam,ftp_file_t *pstuFtpFile) ftp_download(&stuFtpConnectParam,&stuFtpFile); printf("\nstuFtpFile.ncount[%lf]\n",stuFtpFile.nCount); if(stuFtpFile.stream) { fclose(stuFtpFile.stream); /* close the local file */ } s_curl_term(); } static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { ftp_file_t *out = (ftp_file_t *)stream; static int iFlag = 0; static int i = 0; if(!out) { return -1; } //printf("\n %d \n",size*nmemb); if(!out->stream) { /* open file for writing */ out->stream=fopen(out->pchFilename, "wb"); if(!out->stream) { return -1; /* failure, can't open file to write */ } } out->nCount += size*nmemb; return fwrite(buffer, size, nmemb, out->stream); } //int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); int my_progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { static int i=0; i++; if(i%10000==0 && dltotal > 0) { //printf("\n dltotal[%03lf] dlnow[%03lf] ultotal[%03lf] ulnow[%03lf]",dltotal,dlnow,ultotal,ulnow); int nPersent = (int)(100.0*dlnow/dltotal); printf("\n persent[%d%]",nPersent); } return 0; } int ftp_download(ftp_connect_param_t * pstuFtpConnectParam,ftp_file_t *pstuFtpFile) { CURLcode res; CURL *p_curl_handle = NULL; if((NULL == pstuFtpConnectParam) || (NULL == pstuFtpFile) || (0 == strlen(pstuFtpConnectParam->chUrl)) || (0 == strlen(pstuFtpConnectParam->chUserPwd))) { printf("\n param error \n"); return -1; } p_curl_handle = curl_easy_init(); if(NULL == p_curl_handle) { printf("\n s_get_download_file_length if(NULL == p_curl_handle) \n"); return -1; } /* * You better replace the URL with one that works! Note that we use an * FTP:// URL with standard explicit FTPS. You can also do FTPS:// URLs if * you want to do the rarer kind of transfers: implicit. */ curl_easy_setopt(p_curl_handle, CURLOPT_URL,pstuFtpConnectParam->chUrl); curl_easy_setopt(p_curl_handle, CURLOPT_USERPWD, pstuFtpConnectParam->chUserPwd); /* Define our callback to get called when there's data to be written */ curl_easy_setopt(p_curl_handle, CURLOPT_WRITEFUNCTION, my_fwrite); /* Set a pointer to our struct to pass to the callback */ curl_easy_setopt(p_curl_handle, CURLOPT_WRITEDATA, pstuFtpFile); //time out //curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, timeout); curl_easy_setopt(p_curl_handle, CURLOPT_PROGRESSFUNCTION,my_progress_callback ); curl_easy_setopt(p_curl_handle, CURLOPT_PROGRESSDATA,NULL); curl_easy_setopt(p_curl_handle, CURLOPT_NOPROGRESS, 0L); /* We activate SSL and we require it for both control and data */ curl_easy_setopt(p_curl_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL); /* Switch on full protocol/debug output */ curl_easy_setopt(p_curl_handle, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(p_curl_handle); /* always cleanup */ curl_easy_cleanup(p_curl_handle); if(CURLE_OK == res) { /* we success */ fprintf(stdout, "curl told us %d! finish!!!!!\n", res); } else { /* we failed */ fprintf(stderr, "curl told us %d\n", res); } return 0; } int ftp_init(void *param) { s_curl_init(); return 0; } int s_curl_init() { curl_global_init(CURL_GLOBAL_DEFAULT); return 0; } int s_curl_term() { curl_global_cleanup(); return 0; } static size_t save_header(void *ptr, size_t size, size_t nmemb, void *data) { return (size_t)(size * nmemb); } double s_get_download_file_length(ftp_connect_param_t * pstuFtpConnectParam) { double len= 0.0; CURL *p_curl_handle = NULL; CURLcode res; if((NULL == pstuFtpConnectParam) || (0 == strlen(pstuFtpConnectParam->chUrl)) || (0 == strlen(pstuFtpConnectParam->chUserPwd))) { printf("\n s_get_download_file_length param error \n"); return -1; } p_curl_handle = curl_easy_init(); if(NULL == p_curl_handle) { printf("\n s_get_download_file_length if(NULL == p_curl_handle) \n"); return -1; } curl_easy_setopt(p_curl_handle, CURLOPT_URL, pstuFtpConnectParam->chUrl); curl_easy_setopt(p_curl_handle, CURLOPT_HEADER, 1); //只要求header头 curl_easy_setopt(p_curl_handle, CURLOPT_NOBODY, 1); //不需求body curl_easy_setopt(p_curl_handle, CURLOPT_HEADERFUNCTION, save_header); curl_easy_setopt(p_curl_handle, CURLOPT_USERPWD, pstuFtpConnectParam->chUserPwd); res = curl_easy_perform(p_curl_handle); if (res == CURLE_OK) { res= curl_easy_getinfo(p_curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &len); if(CURLE_OK == res) { printf(" curl_easy_getinfo CURLE_OK !\n"); } else { printf("curl_easy_getinfo failed! res = %d\n",res); } } else { printf("\n s_get_download_file_length====== res = %d \n",res); len= -1; } curl_easy_cleanup(p_curl_handle); return len ; } void set_ftp_file(ftp_file_t *pstuFtpFile, char *pchFileName) { if(NULL == pstuFtpFile) { printf("\n if(NULL != pstuFtpFile) set_ftp_file \n "); return; } pstuFtpFile->nFileLength = 0.0; pstuFtpFile->pchFilename = pchFileName; pstuFtpFile->stream = NULL; pstuFtpFile->nPersent = 0; pstuFtpFile->nCount =0.0; } void set_ftp_connect_param(ftp_connect_param_t * pstuFtpConnectParam) { if(NULL == pstuFtpConnectParam) { printf("\n if(NULL == pstuFtpConnectParam) set_ftp_connect_param \n "); return; } memset(pstuFtpConnectParam,0,sizeof(ftp_connect_param_t)); strncpy(pstuFtpConnectParam->chUserName,"anonymous",sizeof(pstuFtpConnectParam->chUserName)-1); strncpy(pstuFtpConnectParam->chPassword," ",sizeof(pstuFtpConnectParam->chPassword)-1); snprintf(pstuFtpConnectParam->chUserPwd,sizeof(pstuFtpConnectParam->chUserPwd), "%s:%s", pstuFtpConnectParam->chUserName, pstuFtpConnectParam->chPassword); strncpy(pstuFtpConnectParam->chUrl,FtpUrl,sizeof(pstuFtpConnectParam->chPassword)-1); }
相关文章推荐
- (二)使用libcurl实现获取目标文件大小, 下载进度显示, 断点续传等功能
- 使用libcurl实现获取目标文件大小, 下载进度显示, 断点续传等功能
- libcurl开源库在Win32程序中使用下载文件显示进度条实例
- 使用libcurl显示下载进度
- 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具
- 使用线程进行App的自动下载安装(带进度显示)
- Android使用OKHttp3实现下载(断点续传、显示运行进度)
- 解决Python爬虫在爬资源过程中使用urlretrieve函数下载文件不完全且避免下载时长过长陷入死循环,并在下载文件的过程中显示下载进度
- Android使用OKHttp3实现下载(断点续传、显示进度)
- 微信小程序使用progress组件实现显示进度功能【附源码下载】
- AsyncTask 的简单使用,给定一个uri地址下载图片,并显示进度条
- ios使用AFN框架下载文件显示下载百分比带进度条
- Android中使用自定义View实现下载进度的显示
- 文件下载之使用AsyncTask并在进度对话框中显示下载进度
- Python3使用requests模块显示下载进度
- Python3使用requests模块显示下载进度
- Android中使用Notification实现应用更新显示下载进度
- C#中使用aria2c进行下载并显示进度条
- Android使用ProgressBar、自定义Notification显示文件下载进度
- libcurl开源库在Win7 + VS2012环境下编译、配置详解 以及下载文件并显示下载进度 demo(转载)