小妞会装机 -- 一个装机软件的开发笔记(六)

来源:互联网 发布:还珠格格小燕子知乎 编辑:程序博客网 时间:2024/05/14 14:26

本文配套程序下载地址为: http://pan.baidu.com/share/link?shareid=358034&uk=3995556177


下载地址获得了,那就下载吧。最简单的,URLDownloadToFile。如何显示进度呢?URLDownloadToFile提供了一个回调,实现这个回调就可以了

STDMETHODIMP CDownloadFileByHttp::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText){    m_eaz->downloadBytes = ulProgress;    return S_OK;}

解决了!

但问题又来了,一个镜像2.2G,下载速度200K,要下载3个小时!体验也太差了些。我用迅雷试了一下,可以达到1.4M!看来需要多线程下载啊。

怎么多线程呢?解决方法有两个,一个是像迅雷一样对单个文件多线程下载,这需要服务器支持。另外一个就是讲镜像文件分割,然后同时下载多个小文件。第二个方法有个好处,就是如果中途程序退出了,已经下载的完整文件不需要再下载了。所以选择第二种方法。

于是又改代码,开了5个线程,同时下载5个文件。但是奇怪的是,只有两个文件同时下载。超过两个URLDownloadToFile就返回错误。不解。google一下,原来是ie的限制。ie缺省就只能同时下载2个。晕。怎么办呢?修改ie设置?可是ie版本那么多,都要去改很麻烦。而且修改ie设置的时候估计360又得弹框了,改也改不了。怎么办呢?

又google。找到迅雷sdk库,将sdk集成进来后,安装包大了0.5M,可实验了一下,效果不理想。因为下载单个文件的时候,迅雷sdk是单线程下载,根本不会提高下载速度,而且必须要安装迅雷。另外在托盘处会弹出下载速度,可是速度经常不更新,不靠谱。

于是又google,这下找到一个下载库,libcurl。看了一下例子,调用起来很简单。而且multithread例子很适合,就把这个例子改了改,集成到程序里面去,效果很好。推荐以后下载就用这个库,而且稍稍将multithread例子改一下,就可以支持多线程下载一个文件。

size_t CDownloadFileByHttp::write_data(void *ptr, size_t size, size_t nmemb, void *stream){    CDownloadFileByHttp *htt = (CDownloadFileByHttp *)stream;    size_t written = fwrite(ptr, size, nmemb, htt->m_pagefile);    htt->m_eaz->downloadBytes += written;    return written;}BOOL CDownloadFileByHttp::DownloadFile(){    BOOL ret = FALSE;    CStringA aurl = CW2A(m_url);    CURL *curl;    curl = curl_easy_init();    curl_easy_setopt(curl, CURLOPT_URL, aurl.GetBuffer()); aurl.ReleaseBuffer();    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CDownloadFileByHttp::write_data);        CStringA afile = CW2A(m_downloadFilePath);    m_pagefile = fopen(afile.GetBuffer(), "wb"); afile.ReleaseBuffer();    if (m_pagefile)        curl_easy_setopt(curl, CURLOPT_FILE, this);    else        goto RETURN;    int i = 0;    while ( i < 5 )    {        if (0 == curl_easy_perform(curl))        {            m_status = DOWNLOADED;            m_eaz->status = DOWNLOADED;            m_eaz->downloadBytes = m_eaz->size;            TheDownloadManagerHelper.OneFileDownloaded(m_eaz);            LOGEx(L"一个文件下载完成: " + m_downloadFilePath);            ret = TRUE;            goto RETURN;        }        else        {            CString msg;            msg.Format(L"Error: Http下载文件失败, file = %s, errorcode = %d", m_downloadFilePath.GetBuffer(), GetLastError());            m_downloadFilePath.ReleaseBuffer();            LOGEx(msg);            m_eaz->downloadBytes = 0;            i++;        }    }    m_eaz->status = NOT_DOWNLOAD;    LOGEx(L"Error: Http下载文件失败: " + m_downloadFilePath);    TheDownloadManagerHelper.m_errorCode = -7; // Http下载文件失败RETURN:    curl_easy_cleanup(curl);    if (m_pagefile)        fclose(m_pagefile);    return ret;}


跑了一下,速度达到了1.4M,和迅雷一样! 好高兴,哈哈

原创粉丝点击