版权声明:本版面文章皆为原创、或参考其他技术网站、博客后自己动手做实验所得,转载请注明出处。
商务合作:lz_kwok@foxmail.com
易开嵌入式工作室
嵌入式系统,OTA功能是十分重要的。linux环境下,使用libcurl,通过http可以很方便实现文件下载功能,并显示文件下载进度。实现方案如下:
首先定义下载地址和下载路径
#define downLoad_url "http://xxxx/downloadExample/update.tar.gz"
#define downLoad_file "/home/xxx/update.tar.gz"
初始化libcurl并配置
CURLcode curl_base::Download(std::string strUrl,std::string filepath)
{
CURLcode res;
char *progress_data = "* ";
FILE* fp = fopen(filepath.c_str(),"wb+");
curl_handle = curl_easy_init();
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, OnDownLoadFile);
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)fp);
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, my_progress_func);
curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, progress_data);
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl_handle,CURLOPT_RESUME_FROM,0); //从0字节开始下载
/* 设置连接超时,单位:毫秒 */
curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, 10000L);
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 10000L);
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 3);
curl_easy_setopt(curl_handle, CURLOPT_URL, const_cast<char*>(strUrl.c_str()));
/* get it! */
res = curl_easy_perform(curl_handle);
/* check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
fclose(fp);
return res;
}
其中,注意要关闭CURLOPT_NOPROGRESS。看下官网解释:
If onoff is to 1, it tells the library to shut off the progress meter completely for requests done with this handle. It will also prevent the CURLOPT_XFERINFOFUNCTION or CURLOPT_PROGRESSFUNCTION from getting called.
回调函数如下:
static size_t OnDownLoadFile(void* buffer,size_t size, size_t nmemb,void* fp)
{
fwrite(buffer, size, nmemb, (FILE*)fp);
fflush((FILE*)fp);
return (size*nmemb);
}
static int my_progress_func(char *progress_data,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
printf("%s %g / %g (%g %%)\n", progress_data, d, t, d*100.0/t);
return 0;
}
下载完成后,进行clean操作:
void curl_base::DownloadFinish()
{
curl_easy_cleanup(curl_handle);
}
主函数:
void *myDownload_run(void *para){
mycurl::my_curl::curl_base curl;
curl.Download(downLoad_url,downLoad_file);
curl.DownloadFinish();
while(1){
sleep(2);
}
}
编译后,查看运行效果:
* 271917 / 364519 (74.5961 %)
* 273365 / 364519 (74.9933 %)
* 273365 / 364519 (74.9933 %)
* 276261 / 364519 (75.7878 %)
* 276261 / 364519 (75.7878 %)
* 277709 / 364519 (76.1851 %)
* 277709 / 364519 (76.1851 %)
* 279157 / 364519 (76.5823 %)
* 279157 / 364519 (76.5823 %)
* 280605 / 364519 (76.9795 %)
* 280605 / 364519 (76.9795 %)
* 282053 / 364519 (77.3768 %)
* 282053 / 364519 (77.3768 %)
* 283501 / 364519 (77.774 %)
* 283501 / 364519 (77.774 %)
* 284949 / 364519 (78.1712 %)
* 284949 / 364519 (78.1712 %)
* 296533 / 364519 (81.3491 %)
* 296533 / 364519 (81.3491 %)
* 297981 / 364519 (81.7464 %)
* 297981 / 364519 (81.7464 %)
* 302325 / 364519 (82.9381 %)
* 302325 / 364519 (82.9381 %)
* 305221 / 364519 (83.7325 %)
* 305221 / 364519 (83.7325 %)
* 306669 / 364519 (84.1298 %)
* 306669 / 364519 (84.1298 %)
* 308117 / 364519 (84.527 %)
* 308117 / 364519 (84.527 %)
* 309565 / 364519 (84.9242 %)
* 309565 / 364519 (84.9242 %)
* 312461 / 364519 (85.7187 %)
* 312461 / 364519 (85.7187 %)
* 313909 / 364519 (86.116 %)
* 313909 / 364519 (86.116 %)
* 315357 / 364519 (86.5132 %)
* 315357 / 364519 (86.5132 %)
* 316805 / 364519 (86.9104 %)
* 316805 / 364519 (86.9104 %)
* 319701 / 364519 (87.7049 %)
* 319701 / 364519 (87.7049 %)
* 321149 / 364519 (88.1021 %)
* 321149 / 364519 (88.1021 %)
* 322597 / 364519 (88.4994 %)
* 322597 / 364519 (88.4994 %)
* 334181 / 364519 (91.6773 %)
* 334181 / 364519 (91.6773 %)
* 335629 / 364519 (92.0745 %)
* 335629 / 364519 (92.0745 %)
* 337077 / 364519 (92.4717 %)
* 337077 / 364519 (92.4717 %)
* 338525 / 364519 (92.869 %)
* 338525 / 364519 (92.869 %)
* 342869 / 364519 (94.0607 %)
* 342869 / 364519 (94.0607 %)
* 344317 / 364519 (94.4579 %)
* 344317 / 364519 (94.4579 %)
* 348661 / 364519 (95.6496 %)
* 348661 / 364519 (95.6496 %)
* 350109 / 364519 (96.0468 %)
* 350109 / 364519 (96.0468 %)
* 351557 / 364519 (96.4441 %)
* 351557 / 364519 (96.4441 %)
* 353005 / 364519 (96.8413 %)
* 353005 / 364519 (96.8413 %)
* 355901 / 364519 (97.6358 %)
* 355901 / 364519 (97.6358 %)
* 358797 / 364519 (98.4303 %)
* 358797 / 364519 (98.4303 %)
* 361693 / 364519 (99.2247 %)
* 361693 / 364519 (99.2247 %)
* 363141 / 364519 (99.622 %)
* 363141 / 364519 (99.622 %)
* 364519 / 364519 (100 %)
OK,完成!!!