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

本文讲述了作者在开发装机软件过程中,遇到的下载速度慢的问题。通过研究发现,IE浏览器默认限制了同时下载的数量。为解决此问题,作者尝试了迅雷SDK和libcurl库。最终,libcurl的多线程下载示例被成功集成,实现了高效的文件下载功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文配套程序下载地址为: 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,和迅雷一样! 好高兴,哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值