读书人

怎么实现CInternetSession上载加速

发布时间: 2013-01-09 09:38:15 作者: rapoo

如何实现CInternetSession下载加速?
下载小文件还可以,可是下载大文件时速度就很慢了,,,感觉跟在网页上右键“目标另存为”的速度差不多,而一些浏览器自带的下载器速度很快,差不多有4倍的下载速度,这种是通过分包下载的吗,将待下载的文件分几段下载,完成后拼接起来。这样的方式通过CInternetSession类可以实现吗?应该怎样将待下载的文件分段呢?
[解决办法]
分段下载

Asynchronous Pluggable Protocols
http://msdn.microsoft.com/en-us/library/aa767743(VS.85).aspx

有个 Passthrough APP development toolkit, 你可以下载来看看...
[解决办法]

类采用线程技术完成http下载

作者: 博云

博客: http://yiyunscu.blog.163.com


#ifndef DOWNLOADTHREAD_H

#define DOWNLOADTHREAD_H


#include "afx.h"

#include "WININET.H"

#include "SpecStrings.h"




#include "afxwin.h"

#include "Afxinet.h"




#include "afxdisp.h"

#include "Shlwapi.h"

#include "atlconv.h"

#ifndef DLL_API

#define DLL_API _declspec(dllimport)

#endif


enum ERROR_CODE

{

RETURN_SUCCESS = 0x100, //操作成功

RETURN_BAD_URL = 0x101, //链接地址错误

RETURN_TIMEOUT = 0x102, //访问超时

RETURN_NETLINK_ERROR = 0x103, //网络连接错误

RETURN_NOT_FOUND = 0x104, //下载文件不存在

RETURN_CODE_ERROR = 0x105, //密码错误

RETURN_FILE_ERROR = 0x106, //本地文件错误

RETURN_THREADCLOSE_ERROR = 0x107, //结束线程错误

RETURN_THREAD_EXIT_OK = 0x108, //线程正常退出

RETURN_QUEST_ERROR = 0x109, //多线程续下载请求服务器失败

RETURN_NOT_HTTPORFTP_QUEST = 0x110, //非HTTP或者FTP请求

RETURN_FILESIZE_ERROR = 0x111, //获取文件大小失败

RETURN_UNKNOWN_ERROR = 0x112 //未知错误

};




class DLL_API CDownloadThread

{

public:

CDownloadThread();

virtual ~CDownloadThread();

public:

/******************************************************************************

函数名称:

GetURLFileInfo

参数:

lpFileURL 下载文件链接, 传入前赋值, 不能为NULL

filename 下载文件名, 为函数运行返回, 不用在传入前赋值

nLen 下载文件长度, 为函数运行返回, 不用在传入前赋值

功能:

获取下载链接的文件信息

*****************************************************************************/

ERROR_CODE GetURLFileInfo(LPCTSTR lpFileURL, char *sourceFileName, DWORD &nLen);

/*****************************************************************************************************

函数名称:

MultiThread

参数:

lpSaveFileName 下载文件的保存文件名, 传入前赋值, 可以为NULL, 此时程序以获取下载文件名保存

nLen 下载文件长度, 为函数运行返回, 传入前赋值, 可以为NULL, 此时程序以运行目录下的downloads目录保存

功能:

下载文件

*****************************************************************************************************/




ERROR_CODE MultiThreadDownloadFile(int threadCount, LPCTSTR lpSaveFileName, LPCTSTR lpSaveDirectory);



/****************************************************************************************************

函数名称:

SetTimeOut

参数:

ConnectTimeOut 连接超时, 以秒计

SendTimeOut 发送超时, 以秒计

RecTimeOut 接收超时, 以秒计

功能:

设置下载超时

*****************************************************************************************************/

void SetTimeOut(DWORD ConnectTimeOut, DWORD SendTimeOut, DWORD RecTimeOut, DWORD QueryTimeOut);




//清除临时资源

void CleanTempSource();

//强制关闭下载, 并调用CleanTempSource清除临时资源

ERROR_CODE TerminateDownload();




int GetThreadCount() const; //获取最大下载线程数

float GetDownLoadSpeed() const; //获取下载速度

DWORD GetNowFileSize() const; //获取当前已下载文件大小

COleDateTimeSpan GetElapsedTime() const; //获取下载用时




private:

int nMaxThreadCount;

BOOL m_bForceReload;

//关闭事件标志

BOOL bExit;




//Internet会话

CInternetSession *session;

COleDateTime startTime; //开始时间

COleDateTimeSpan elapsed; //耗时




BOOL DownLoadComplete; //下载完成标志

ERROR_CODE ReturnCode;

BOOL StartFlag; //开始下载标志




//协议类型

DWORD dwType;




//功能函数

void URLDecodeToGB(CString &source);

void UTF8ToGB(CString &szstr); //UTF-8转化成GB2312




//下载文件信息

LPCTSTR m_url;

CString m_RedirectUrl;

CString m_filename;

CString m_SaveFileName;




CString m_SaveDirectory; //下载文件保存目录, 如"download\"

CString m_SourceDirectory; //下载文件保存目录, 如"download"




DWORD m_filelength;






DWORD m_infoStatusCode;

float m_transferRate;



DWORD dwRecTimeOut;

DWORD dwSendTimeOut;

DWORD dwConnectTimeOut;

DWORD dwDownFileSize;

DWORD dwPartFileSize;

DWORD dwQueryTimeOut;




//线程句柄

HANDLE hQuery; //获取信息句柄

HANDLE *hDownloadArray; //下载线程句柄组

HANDLE hMerge; //合并文件句柄

HANDLE hMutex; //互斥互斥对象

HANDLE hShare;




//多线程下载中每个线程起始下载字节

DWORD m_StartByte;

DWORD m_EndByte;

int m_threadIndex;




//获取文件信息线程

static DWORD WINAPI GetDownloadFileInfoThread(LPVOID lpParameter);

//合并文件线程

static DWORD WINAPI MergerFile(LPVOID lpParameter);






//HTTP下载函数

ERROR_CODE GetHttpFile(LPCTSTR lpSaveFile, DWORD bStartBytes, DWORD bEndBytes);

//FTP下载函数

ERROR_CODE GetFtpFile(LPCTSTR lpSaveFile, DWORD bStartBytes, DWORD bEndBytes);




//重定向检查

ERROR_CODE OpenRedirectHttpURL(CString &strOldLocation, CInternetSession *session);

//设置超时线程, 因为微软中的超时设置存在BUG, 需要采线程技术解决

//设置连接超时线程

static DWORD WINAPI SetConnectionTimeOut(LPVOID lpParameter);

//设置发送超时线程

static DWORD WINAPI SetSendTimeOut(LPVOID lpParameter);

//设置接收超时线程

static DWORD WINAPI SetRecTimeOut(LPVOID lpParameter);




//下载线程

static DWORD WINAPI DownloadFileThread(LPVOID lpParameter);

/*************************************************************************

*

* 函数名称:

* CreateSourceDirectory()

*

* 参数:

* LPCTSTR lpDirectoryPath

* 若为NULL, 则创建在程序运行目录下的downloads文件下, 否则创建为lpDirectoryPath目录下

*

* 说明:

* //创建临时资源文件夹

* 返回文件夹目录

*

*************************************************************************/

void CreateSourceDirectory(LPCTSTR lpDirectoryPath);

DWORD GetProtocalType() const;

};

#endif

上面是头文件定义, 下面是cpp文件:


#define DLL_API _declspec(dllexport)




#include "DownloadThread.h"




#define BUFFER_SIZE 4095

const TCHAR szHeaders[] = _T("Accept: */*\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)\r\n");//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CDownloadFile::CDownloadFile(){ m_TimeOut = 0; m_bForceReload = true; m_dwThreadID = 0; m_hNotify = NULL; m_dwMsgID = 0; m_wFileID = 0;}CDownloadFile::~CDownloadFile(){}




//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////




#pragma comment(lib,"Shlwapi.lib")

#pragma comment(lib,"WinInet.lib")

#pragma comment(lib, "Shlwapi.lib")




CDownloadThread::CDownloadThread()

{

nMaxThreadCount = 2;

m_filelength = 0;

dwQueryTimeOut = 30000;




dwConnectTimeOut = 4000; //默认连接超时为4s

dwSendTimeOut = 4000; //默认发送超时为4s

dwRecTimeOut = 30000; //默认接收超时为30s

m_bForceReload = true;



dwDownFileSize = 0;

m_transferRate = 0.0;

bExit = false;

DownLoadComplete = false;

StartFlag = false;




m_RedirectUrl.Empty();




m_filename.Empty();

m_filelength = 0;




hQuery = NULL; //获取信息句柄

hDownloadArray = NULL; //下载线程句柄组

hMerge = NULL;

hMutex = NULL;

m_threadIndex = 1;




session = NULL;

m_SaveFileName.Empty();

m_SourceDirectory.Empty();

hShare = NULL;

}


[解决办法]
人家写的有注释的呀

读书人网 >VC/MFC

热点推荐