使用libcurl显示下载进度

来源:互联网 发布:淘宝上的卖家中心在哪 编辑:程序博客网 时间:2024/04/29 17:44


(1)s_get_download_file_length函数获取目标文件大小。


(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); //不需求bodycurl_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);}


0 0