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

源码如下:

//g++ -g curl_range.cpp -o curl_range -lcurl -lm
//
#include <iostream>
#include <string>
#include <math.h>
#include <curl/curl.h>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\n", TotalToDownload, NowDownloaded);int i = 0;printf("%3.0f%% [", fractionDownloaded * 100);for(; i < dot; i++)printf("="); // full partfor(; i < totalDot; i++)printf(" "); // remainder partprintf("]\n");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!\n";}//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

libcurl 编程进度条和range请求源码示例相关推荐

  1. springboot:实现文件上传下载实时进度条功能【附带源码】

    0. 引言 记得刚入行的时候,做了一个文件上传的功能,因为上传时间较久,为了用户友好性,想要添加一个实时进度条,显示进度.奈何当时技术有限,查了许久也没用找到解决方案,最后不了了之. 近来偶然想到这个 ...

  2. 【iOS-Cocos2d游戏开发之十五】详解CCProgressTimer 进度条并修改cocos2d源码实现“理想”游戏进度条!...

    为什么80%的码农都做不了架构师?>>>     李华明Himi 原创,转载务必在明显处注明: 转载自 [黑米GameDev街区] 原文链接:  http://www.himigam ...

  3. 利用urllib2实现http post请求源码示例

    在python中利用urllib2或是pycurl都可以实现http POST请求功能,下面是源码: #!/usr/bin/env python #encoding: utf-8 #descripti ...

  4. 学生学python编程---实现贪吃蛇小游戏+源码

    学生学python编程---实现贪吃蛇小游戏+源码 前言 主要设计 1.蛇的表示 2.蛇怎么移动? 3.玩家控制小蛇移动功能的实现 4.如何判定游戏结束? 应用知识点 1.python知识点 1.1 ...

  5. RocketMQ源码(十七)—Broker处理DefaultMQPushConsumer发起的拉取消息请求源码

    转载来源: RocketMQ源码(19)-Broker处理DefaultMQPushConsumer发起的拉取消息请求源码[一万字]_刘Java的博客-CSDN博客 此前我们学习了RocketMQ源码 ...

  6. RocketMQ源码(19)—Broker处理DefaultMQPushConsumer发起的拉取消息请求源码【一万字】

    基于RocketMQ release-4.9.3,深入的介绍了Broker处理DefaultMQPushConsumer发起的拉取消息请求源码. 此前我们学习了RocketMQ源码(18)-Defau ...

  7. Libcurl的编译_HTTP/HTTPS客户端源码示例

    HTTP/HTTPS客户端源码示例 环境:  zlib-1.2.8  openssl-1.0.1g  curl-7.36 Author:  Kagula LastUpdateDate: 2016-05 ...

  8. 【游戏编程扯淡精粹】EASTL源码阅读

    [游戏编程扯淡精粹]EASTL源码阅读 侯捷先生在<漫谈程序员与编程> 中讲到 STL 运用的三个档次:"会用 STL,是一种档次.对 STL 原理有所了解,又是一个档次.追踪过 ...

  9. Tomcat 处理 HTTP 请求源码分析(下)【转】

    原文地址:https://www.infoq.cn/article/zh-tomcat-http-request-2 很多开源应用服务器都是集成 tomcat 作为 web container 的,而 ...

最新文章

  1. 揭秘TensorFlow:Google开源到底开的是什么?
  2. Python实训day12pm【答辩要求、定时器】
  3. Linux中逻辑卷的快照与还原
  4. java输出一副扑克牌_JAVA编一副扑克牌
  5. Java Collections工具类
  6. 动态规划算法 - 钢条切割问题
  7. php const用法详解
  8. IT项目中的6类知识转移
  9. MyEclipse + Tomcat + Eclipse 开发调试WEB应用
  10. ERPSYSTEM开发教程01 框架介绍
  11. ISCROLL4 简述
  12. atitit.元编程总结 o99
  13. 大众点评字体_大众点评字体解析
  14. 一起学JAVA 学习路径 知识体系
  15. 通过Java创建Socket 连接到服务器
  16. iOS App页面置灰
  17. 格式化日期时间字符串 Get-Date -Uformat , -format
  18. 移动应用实战(移动OA)之五_会议室管理之二
  19. 【网络资源学习笔记】ShellCode相关内容学习
  20. 投资高手三十年投资经验总结的18条真谛

热门文章

  1. Ubuntu 安装 IPython、jupyter notebook
  2. smarty mysql demo_PHP Smarty模版简单使用方法
  3. 《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽
  4. html web上传文件原理,Web上传文件的原理及实现
  5. python dataframe 分位数_Python pandas.DataFrame.quantile函数方法的使用
  6. uefi怎么添加linux启动项,LINUX下EFIBOOTMGR的使用,删除UEFI主板多余启动项和添加启动项...
  7. echarts x轴文字个数太多_echarts x轴标签文字过多导致显示不全,最有效的3种解决方法...
  8. python中where函数_如何在python中基于Where函数获取两列值
  9. java包装_Java基础之神奇的包装类(一)
  10. C语言随机字母生成,C++ 随机数字以及随机数字加字母生成的案例