如何实现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;
}
[解决办法]
人家写的有注释的呀