首页 > libcurl 编程进度条和range请求源码示例

libcurl 编程进度条和range请求源码示例

在下面的源码中,我将展示如何使用libcurl提供的进度条功能,以及如何发送range请求, 同时提供了限速功能。

源码如下:

//g++ -g curl_range.cpp -o curl_range -lcurl -lm
//
#include 
#include 
#include 
#include using namespace std;int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUpload)
{//how wide you want the progress bar to be ?int totalDot = 80;double fractionDownloaded = 0.0;if(TotalToDownload != 0)fractionDownloaded = NowDownloaded / TotalToDownload;//注意0不能为分母elsefractionDownloaded = 0;//the full part of progress barint dot = round(fractionDownloaded * totalDot);//create the progress bar, but control to printif(dot % 10 == 0){printf("total: %0.0f, now: %0.0f
", TotalToDownload, NowDownloaded);int i = 0;printf("%3.0f%% [", fractionDownloaded * 100);for(; i < dot; i++)printf("="); // full partfor(; i < totalDot; i++)printf(" "); // remainder partprintf("]
");fflush(stdout); //avoid output buffering problems}return 0;
}int download (string url, string local_file, int down_speed)
{CURL *curl;CURLcode res;FILE *fp;curl = curl_easy_init ();if (curl){//Open Filefp = fopen (local_file.c_str (), "w");if (fp == NULL)cout << "File cannot be opened" << endl;curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);//这里限速 XX KB/scurl_easy_setopt (curl, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) down_speed * 1024);curl_easy_setopt (curl, CURLOPT_RANGE, "0-100000000"); //设置range请求, 只下载前100MB// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, NULL);curl_easy_setopt (curl, CURLOPT_WRITEDATA, fp);curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0);//禁用内部CURL进度显示条,假如我们提供了自定义的curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_func);//限速下载res = curl_easy_perform (curl);if (res)cout << "Cannot grab the File!
";}//Clean up the resourcescurl_easy_cleanup (curl);//Close the filefclose (fp);return 0;
}int main (int argc, char *argv[])
{string url ("http://cdimage.ubuntu.com/releases/14.04/release/ubuntu-14.04-desktop-amd64+mac.iso");string filepath ("./a.iso");int downspeed = 600;int ret = download (url, filepath, downspeed);cout << "download [result]: " << ret << endl;return 0;
}

下载过程中,和下载完成时的运行截图:





几个知识点强调:

CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);  

      1. 设置下载数据的回调函数.      

     option:      

     CURLOPT_WRITEFUNCTION //设置回调函数,这个必须得有,否则libcurl的下载数据将直接显示在终端

         回调函数原型为: size_t function( void *ptr, size_t size, size_t nmemb, void *userp); 必须返回数据长度, 函数将在libcurl接收到数据后被调用。

         void *ptr是下载回来的数据.

         void *userp是用户指针, 用户通过这个指针传输自己的数据.

     CURLOPT_WRITEDATA 

      设置回调函数中的void *userp指针的来源。

      2. 下载进度控制.

     option:

     CURLOPT_NOPROGRESS  

       为了使CURLOPT_PROGRESSFUNCTION被调用. CURLOPT_NOPROGRESS必须被设置为false.如果没有下面的进度函数,将使用默认的进度条展示在终端

     CURLOPT_PROGRESSFUNCTION

       CURLOPT_PROGRESSFUNCTION 指定的函数正常情况下每秒被libcurl调用一次.

     CURLOPT_PROGRESSDATA

       CURLOPT_PROGRESSDATA指定的参数将作为CURLOPT_PROGRESSFUNCTION指定函数的参数. 

     整个处理与下载数据回调的处理相同. 

     3. 其它常用属性. 

     option:

     CURLOPT_URL

       设置访问的URI.

     CURLOPT_NOSIGNAL

       屏蔽其它信号.

     CURLOPT_HEADER

       取数据时连同HTTP头部一起取回.

     CURLOPT_HEADERFUNCTION

     CURLOPT_HEADERDATA

       只取HTTP头部数据, 处理与下载数据回调的处理相同. 

     CURLOPT_TIMEOUT

       超时时间.

     CURLOPT_CONNECTIONTIMEOUT

       连接等待时间.

     CURLOPT_FOLLOWLOCATION

     设置支持302重定向

     CURLOPT_RANGE

      断点续传, 指定传输分片, 格式:"0-200", 在上面源码的进度条函数中,我们可以看到设置range中,我们得到的TotalToDownload只是一个该分片的长度,而非整个文件的长度, 同时NowDownloaded会每秒刷新, 长度不断增大, 最后直至达到该分片的长度.

参考文献:

[1].http://blog.chinaunix.net/uid-20692625-id-3203258.html

更多相关:

  • 在线上服务器上执行下面的命令 curl -vo /dev/null 'http://120.52.72.46:80/fileshare3010.dfiles.eu/c3pr90ntcsf0/auth-1375626538db3c073c81647e872cab8f-210.186.189.166-676861082-14640452...

  • 使用libcurl多线程下载大文件的基本思想: 首选打开文件,将文件等分为指定的片段,使用http range下载,一个线程下载一个片段,当线程下载片段时,它们将数据写到打开文件的指定位置,类似BT文件下载的方式(这样片段下载完成后不用再合并),当所有的子线程下载完成后,这个大文件也就随之下载完成了。 下面是相关源码: //g...

  • 这个例子来自参考文献[1], 那里有很多小bug,我都做了修改,在这里不一一说明了。ncurse界面编程比较容易入门,就是几个接口,网上资料很多,这里不详述了。 //gcc -g mget.c -o mget -lcurl -lncurses -lm // #include #include

  • 这是一个简单的获取远程文件大小的源码,我们可以改写为大批量异步的形式. #include #include size_t get_size_struct(void* ptr, size_t size, size_t nmemb, void* data){return (size_t)...

  • 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明。否则将追究法律责任。http://blog.csdn.net/mayongzhan - 马永占,myz,mayongzhan 首先声明本模拟不稳定,有时会出现登陆不进去.模拟的原理请参考blog.csdn.net/mayongzhan的文章,相关...