The key section code is as follows:
#include "curl.h"
#pragma comment (lib, "Libcurl.lib")
size_t cros_downloaddlg::getcontentlengthfunc (void * ptr, size_t size, size_t nmemb, void * stream)
{
Longlong len = 0;
int r = sscanf ((const char *) PTR, "content-length:%i64d\n", &len);
if (R)
* ((Longlong *) stream) = Len;
return size * NMEMB;
}
Get the download file size based on the URL
Longlong cros_downloaddlg::getdownloadfilesize (const char* URL)
{
Double lensize = 0.0;
for (int itry = 0; itry < 3; Itry + +)//Because curl_easy_perform may have sporadic curle_write_error errors, add retry mechanism
{
CURL *handle = Curl_easy_init ();
Curl_easy_setopt (handle, Curlopt_url, URL);
Curl_easy_setopt (Handle, Curlopt_header, 1);
Curl_easy_setopt (Handle, curlopt_followlocation, 1);
Curl_easy_setopt (Handle, Curlopt_nobody, 1);
Curlcode res = curl_easy_perform (handle), Resgetinfo = CURLE_OK;
if (res = = CURLE_OK) {
Resgetinfo = Curl_easy_getinfo (handle, Curlinfo_content_length_download, &lensize);
if (CURLE_OK = = Resgetinfo) {
Curl_easy_cleanup (handle);
Return (Longlong) lensize;
}
}
Curl_easy_cleanup (handle);
Sleep (200);
}
return 0;
}
size_t Cros_downloaddlg::d ownloadpackage (void *ptr, size_t size, size_t nmemb, void *userdata)
{
if (!ptr | |!userdata)
return 0;
Return fwrite (PTR, size, NMEMB, (FILE *) userdata);
}
int Cros_downloaddlg::assetsmanagerprogressfunc (void *ptr, double totaltodownload, double nowdownloaded, double Totaltoupload, double nowuploaded)
{
if (m_bstop)
return-1;
if (Totaltodownload > 0.0)
{
cros_downloaddlg* Pdlg = (cros_downloaddlg*) ptr;
Pdlg->m_lprocesssize = (longlong) nowdownloaded;
Pdlg->sendmessage (wm_downloadproc_msg, 1, 0);
}
return 0;
}
/*
0 Set Total size
1 Setting the current download
2 Download complete
3 Users stop downloading, other exceptions terminate the download
4 download exceptions caused by network problems
5 Device disconnection
6 Insufficient disk space left
*/
UINT Cros_downloaddlg::D ownloadproc (LPVOID lpparam)
{
Using Curl for download
String surl = Cstringconverter::unicode2ansi (strurl.getstring ()), Ssavepath = Cstringconverter::unicode2ansi ( Strsavepath.getstring ());
Longlong Local_file_len = GetFileSize (Strsavepath);
Pdlg->m_llocalfilecursize = Local_file_len;
Curl_global_init (Curl_global_default);
Longlong Remote_file_len = getdownloadfilesize (Surl.c_str ());
if (!remote_file_len)
{
Pdlg->sendmessage (wm_downloadproc_msg, 4, 0);//network Problem acquisition failed
return 0;
}
Pdlg->m_ltotalsize = Remote_file_len;
Pdlg->sendmessage (wm_downloadproc_msg, 0, 0);
if (Local_file_len = = Remote_file_len)
{
Pdlg->sendmessage (wm_downloadproc_msg, 2, 0);
return 0;
}
When you get the exact size, you should determine if the Strsavepath space is sufficient first
if (Remote_file_len >= (Pdlg->m_uldiskspacemax))
{
Pdlg->sendmessage (wm_downloadproc_msg, 6, 0);
return 0;
}
FILE *FP = fopen (Ssavepath.c_str (), "ab+");
if (!FP)
{
Pdlg->sendmessage (wm_downloadproc_msg, 3, 0);
return 0;
}
Longlong filesize = 0;
M_pcurl = Curl_easy_init ();//curl initialization
Curlcode Res;
Curl_easy_setopt (M_pcurl, Curlopt_url, Surl.c_str ());//Set Curl link
Curl_easy_setopt (M_pcurl, curlopt_connecttimeout,5);//Set connection timeout, in seconds
Curl_easy_setopt (M_pcurl, Curlopt_headerfunction,getcontentlengthfunc);
Curl_easy_setopt (M_pcurl, Curlopt_headerdata, &filesize);
Curl_easy_setopt (M_pcurl, Curlopt_resume_from_large, Local_file_len);//Breakpoint Download Settings
Curl_easy_setopt (M_pcurl, curlopt_writefunction, downloadpackage);
Curl_easy_setopt (M_pcurl, Curlopt_writedata, FP);//Set data to be written to the file stream FP
Curl_easy_setopt (M_pcurl, curlopt_followlocation, 1L);//Set the relocation URL, use automatic jump, return to the head of the location (the general direct request URL not found), Continue to request location-corresponding data
Curl_easy_setopt (M_pcurl, curlopt_maxredirs,5);//number of lookups to prevent finding too deep
Curl_easy_setopt (M_pcurl, curlopt_noprogress, false);//set to False below to set the progress response function
Curl_easy_setopt (M_pcurl, curlopt_progressfunction, assetsmanagerprogressfunc);//Progress response function
Curl_easy_setopt (M_pcurl, Curlopt_progressdata, PDLG);//Data Transfer Object
Curl_easy_setopt (M_pcurl, curlopt_verbose,1l);
res = Curl_easy_perform (m_pcurl);
Curl_easy_cleanup (M_pcurl);
Curl_global_cleanup ();
M_pcurl = NULL;
if (res! = CURLE_OK)
{
Fclose (FP);
if (res = = curle_aborted_by_callback)//Click Stop download
Pdlg->sendmessage (wm_downloadproc_msg, 3, 0);
else if (res = = curle_recv_error)//Disconnect/* 56-failure in Receiving network data */
Pdlg->sendmessage (wm_downloadproc_msg, 4, 0);
Else
Pdlg->sendmessage (wm_downloadproc_msg, 3, 0);
return 0;
}
Fclose (FP);
Pdlg->sendmessage (wm_downloadproc_msg, 2, 0);
return 0;
}
void Cros_downloaddlg::onclickbtnstop ()
{
if (M_pcurl) {
Curl_easy_pause (M_pcurl, CURLPAUSE_RECV);
if (Idyes = = ShowMessage (Ids_def_ros_sure_to_stop, Ciphoneutil::getapplicationname (), sm_icon_question| Sm_yes_and_no)) {
M_btnstop.enablewindow (FALSE);
M_bstop = true;
Return
}
Curl_easy_pause (M_pcurl, Curlpause_recv_cont);
}
}
http://blog.csdn.net/dingxz105090/article/details/52621614
Using Libcurl to implement breakpoint downloads