libcurl 编程进度条和range请求源码示例
在下面的源碼中,我將展示如何使用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请求源码示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: libcurl远程获取文件大小源码
- 下一篇: ncurse界面编程多线程示例