vc++ socket实现的支持断点续传的下载器

网上找了一堆代码,有用wininet的,还有用socket的,整理了半天,还是觉得socket靠谱。


只支持内存中断点续传。如果要加上在磁盘上断点续传,原理也差不多,不是本文重点。


注释:

1. CByteBufferVector是一个缓存池,动态分配BYTE形数组空间用的。代码略,可以简单看成BYTE数组。

2. GetStringA是一个CString转CStringA的函数,无需多说。

3. 除了win socket基本没有其它依赖,噢对,ATL::CString除外……


头文件:

class CSocketDownloader;


/**
 *	下载任务
 */
class CDownloadTask
{
    friend class CSocketDownloader;


public:


    CDownloadTask();


    CStringA GetUrlA() const;
    CStringA GetAgnetA() const;
    void ParseUrl();
    
    int Percentage() const;
    DWORD RemainTimeSec(DWORD dwTickElapsed, unsigned int uBytesTransferred) const;


    CString         m_strUrl;           // 下载地址
    CString         m_strAgent;         // 用户agent
    int             m_nMaxTryCount;     // 最多重试次数(重定向不算重试,默认20次)
    int             m_nTimeoutSec;      // socket超时(秒,默认10秒)
    int             m_nPort;            // 端口(默认80)
    HWND            m_hWnd;             // 接收下载进度消息的窗口句柄
    LONG            *m_pTerminate;      // 指向是否中止的标志位,一般由用户界面操作(如点击“取消”按钮)更改此值


protected:


    CStringA        m_strAbsoluteUrlA;
    CStringA        m_strQueryA;
    CStringA        m_strHostA;
    unsigned int    m_uReadBytes;
    unsigned int    m_uTotalBytes;
};


/**
 *	socket实现的断点续传下载器
 */
class CSocketDownloader
{
public:
    CSocketDownloader();
    virtual ~CSocketDownloader();


    // 下载到一个buffer
    DWORD DownloadToBuffer(CDownloadTask &task, CByteBufferVector &bufVec);


    // 下载到一个文件
    DWORD DownloadToFile(CDownloadTask &task, CString strOutputFile);


protected:


    DWORD DoDownloadToBuffer(CDownloadTask &task, CByteBufferVector &bufVec);
    DWORD ConnectServer(const CDownloadTask &task, SOCKET hSocket);
    DWORD DoDownloadToBufferInner(CDownloadTask &task, CByteBufferVector &bufVec, SOCKET hSocket);
    
    int GetSleepSecCount(int nTryCount) const;
    int GetBufferSize(const CDownloadTask &task) const;
    CStringA GenerateRequest(CDownloadTask &task) const;


};


CPP文件:

#include <math.h>
#include <time.h>


const int BLOCK_SIZE = 1024 * 64;
const int DEFAULT_MAX_TRY = 20;
const int DEFAULT_TIMEOUT = 10;


//////////////////////////////////////////////////////////////////////////
// 下载任务
//////////////////////////////////////////////////////////////////////////


CDownloadTask::CDownloadTask()
    : m_nPort(INTERNET_DEFAULT_HTTP_PORT),
    m_nMaxTryCount(DEFAULT_MAX_TRY),
    m_uReadBytes(0),
    m_uTotalBytes(0),
    m_nTimeoutSec(DEFAULT_TIMEOUT),
    m_hWnd(NULL),
    m_pTerminate(NULL)
{


}


CStringA CDownloadTask::GetUrlA() const
{
    return GetStringA(m_strUrl);
}


CStringA CDownloadTask::GetAgnetA() const
{
    return GetStringA(m_strAgent);
}


void CDownloadTask::ParseUrl()
{
    m_strAbsoluteUrlA = m_strHostA = m_strQueryA = "";


    CStringA strUrlA = this->GetUrlA();
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值