CInternetDownload.h
#pragma once
class CDownloadDlg;
class CInternetDownload
{
public:
typedef struct
{
DWORD nStart;//文件片段的起始位置
DWORD nEnd;//文件片段的长度
size_t nIndex;//当前线程的编号
size_t nTotal;
CInternetDownload* pThis;
} ThreadParam;
CInternetDownload(CDownloadDlg* pDlg);
virtual ~CInternetDownload(void);
virtual int Download(const CString& strUrl, size_t nThreads);
protected:
static CString s_strUrl;
static CDownloadDlg* s_pDlg;
virtual DWORD GetFileLength(const CString& strUrl) = 0;
virtual CFile* GetInternetFile(LPVOID) = 0;
static UINT ServerWorkerThread(LPVOID lpParam);
CInternetSession internetSession;
private:
CFile* m_internetFile;
};
InternetDownload.cpp
#include "StdAfx.h"
#include "./internetdownload.h"
#include "DownloadDlg.h"
CDownloadDlg* CInternetDownload::s_pDlg = NULL;
CString CInternetDownload::s_strUrl;
CInternetDownload::CInternetDownload(CDownloadDlg* pDlg)
: m_internetFile(NULL)
{
s_pDlg = pDlg;
}
CInternetDownload::~CInternetDownload(void)
{
}
UINT CInternetDownload::ServerWorkerThread(LPVOID lpParam)
{
ThreadParam *pParam = static_cast<ThreadParam *>(lpParam);
CFile *pFile = pParam->pThis->GetInternetFile(lpParam);
if (!pFile)
return -1;
CFile localFile;
CString strFileName;
strFileName.Format("c://temp.part%d", pParam->nIndex);
if (!localFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite))
return -1;
char * const pBuffer = new char[1024];
DWORD nLeft = pParam->nEnd - pParam->nStart + 1;
while (TRUE)
{
int nRead = pFile->Read(pBuffer, nLeft > 1024 ? 1024 : nLeft);
localFile.Write(pBuffer, nRead);
if (nRead < 1024)
break;
nLeft -= nRead;
}
localFile.Close();
delete []pBuffer;
pFile->Close();
delete pFile;
s_pDlg->PostMessage(WM_DOWNLOADED_MESSAGE, pParam->nTotal, pParam->nIndex);
delete pParam;
pParam = NULL;
return 0;
}
int CInternetDownload::Download(const CString& strUrl, size_t nThreads)
{
s_strUrl = strUrl;
DWORD nFileSize = GetFileLength(strUrl);
UINT nSegmentLength = (nFileSize + nThreads - 1) / nThreads;
for (size_t i = 0; i < nThreads; i++)
{
ThreadParam *lpParam = new ThreadParam;
//memset(lpParam, '/0', sizeof(ThreadParam));
lpParam->nTotal = nThreads;
lpParam->nIndex = i;
lpParam->nStart = nSegmentLength * i;
lpParam->nEnd = lpParam->nStart + nSegmentLength - 1;
lpParam->pThis = this;
if (lpParam->nEnd >= nFileSize)
lpParam->nEnd = nFileSize - 1;
AfxBeginThread(ServerWorkerThread, static_cast<LPVOID>(lpParam), THREAD_PRIORITY_NORMAL, 0, 0, NULL);
//CreateThread(NULL, 0, ServerWorkerThread, (LPVOID)i, 0, 0);
}
return 0;
}
FtpDownload.h
#pragma once
#include "InternetDownload.h"
class CFtpDownload : public CInternetDownload
{
public:
CFtpDownload(CDownloadDlg* pDlg);
virtual ~CFtpDownload(void);
// int Download(const CString& strUrl, size_t nThreads);
private:
DWORD GetFileLength(const CString& strUrl);
CFile* GetInternetFile(LPVOID lpParam);
};
FtpDownload.cpp
#include "StdAfx.h"
#include "./ftpdownload.h"
#include "DownloadDlg.h"
#include <winsock2.h>
#include "shlwapi.h"
#pragma comment(lib, "Wininet.lib")
#pragma comment(lib, "shlwapi.lib")
CFtpDownload::CFtpDownload(CDownloadDlg* pDlg)
: CInternetDownload(pDlg)
{
// s_pDlg = pDlg;
}
CFtpDownload::~CFtpDownload(void)
{
}
CFile* CFtpDownload::GetInternetFile(LPVOID lpParam)
{
ThreadParam *pParam = static_cast<ThreadParam *>(lpParam);
CFtpConnection *pFtpConn = NULL;
CString strServerName, strObject, strUserName, strPassword;
DWORD dwServiceType;
INTERNET_PORT nPort;
if (!AfxParseURLEx(s_strUrl, dwServiceType, strServerName, strObject, nPort, strUserName, strPassword) || dwServiceType != INTERNET_SERVICE_FTP)
{
TRACE(_T("Not a ftp Quest! /n"));
}
pFtpConn = internetSession.GetFtpConnection(strServerName, strUserName, strPassword);
CString strFtpCommand;
strFtpCommand.Format("REST %d", pParam->nStart);
if (!FtpCommand(*pFtpConn, FALSE, FTP_TRANSFER_TYPE_ASCII, strFtpCommand, 0, 0))
{
int i = WSAGetLastError();
return NULL;
}
CFile *pFile = pFtpConn->OpenFile(strObject);
return pFile;
}
/*
int CFtpDownload::Download(const CString& strUrl, size_t nThreads)
{
DWORD nFileSize = GetFileLength(strUrl);
s_strUrl = strUrl;
UINT nSegmentLength = (nFileSize + nThreads - 1) / nThreads;
for (size_t i = 0; i < nThreads; i++)
{
ThreadParam *lpParam = new ThreadParam;
//memset(lpParam, '/0', sizeof(ThreadParam));
lpParam->nTotal = nThreads;
lpParam->nIndex = i;
lpParam->nStart = nSegmentLength * i;
lpParam->nEnd = lpParam->nStart + nSegmentLength - 1;
lpParam->pThis = this;
if (lpParam->nEnd >= nFileSize)
lpParam->nEnd = nFileSize - 1;
AfxBeginThread(ServerWorkerThread, static_cast<LPVOID>(lpParam), THREAD_PRIORITY_NORMAL, 0, 0, NULL);
//CreateThread(NULL, 0, ServerWorkerThread, (LPVOID)i, 0, 0);
}
return 0;
}
*/
DWORD CFtpDownload::GetFileLength(const CString& strUrl)
{
CInternetSession internetSession;
CFtpConnection *pFtpConn = NULL;
CString strServerName, strObject, strUserName, strPassword;
DWORD dwServiceType;
INTERNET_PORT nPort;
if (!AfxParseURLEx(strUrl, dwServiceType, strServerName, strObject, nPort, strUserName, strPassword) || dwServiceType != INTERNET_SERVICE_FTP)
{
TRACE(_T("Not a ftp Quest! /n"));
return -1;
}
pFtpConn = internetSession.GetFtpConnection(strServerName, strUserName, strPassword);
//FtpCommand("REST 1024");
/* if (!FtpCommand(*pFtpConn, FALSE, FTP_TRANSFER_TYPE_ASCII, "REST 1024", 0, 0))
return -1;*/
CInternetFile *pFile = pFtpConn->OpenFile(strObject);
DWORD nFileSize = FtpGetFileSize(*pFile, 0);
pFile->Close();
delete pFile;
return nFileSize;
}
HttpDownload.h
#pragma once
#include "InternetDownload.h"
class CHttpDownload : public CInternetDownload
{
public:
CHttpDownload(CDownloadDlg* pDlg);
virtual ~CHttpDownload(void);
private:
// static UINT ServerWorkerThread(LPVOID lpParam);
DWORD GetFileLength(const CString& strUrl);
CFile* GetInternetFile(LPVOID lpParam);
public:
// int Download(const CString& strUrl, int nThreads);
int FormatRequestHeader(void);
};
HttpDownload.cpp
#include "StdAfx.h"
#include "./httpdownload.h"
#include "DownloadDlg.h"
static const char szHeaders[] = "Accept: */*/r/nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)/r/n";
CFile* CHttpDownload::GetInternetFile(LPVOID lpParam)
{
ThreadParam *pParam = static_cast<ThreadParam *>(lpParam);
DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;
CString strHeader;//请求头
strHeader.Format("%sRange: bytes=%d-%d/r/n", szHeaders, pParam->nStart, pParam->nEnd);//pParam->nIndex * 8192);//, 1024 * 1024);
return internetSession.OpenURL(s_strUrl, 1, dwFlag, strHeader, -1);
}
/*
UINT CHttpDownload::ServerWorkerThread(LPVOID lpParam)
{
//size_t nIndex = reinterpret_cast<size_t>(lpParam);//第几个文件片段
ThreadParam *pParam = static_cast<ThreadParam *>(lpParam);
char * const pBuffer = new char[1024];
//for (int i = 0; ; i++)
while (TRUE)
{
int nRead = pHttpFile->Read(pBuffer, 1024);
localFile.Write(pBuffer, nRead);
if (nRead < 1024)
break;
}
localFile.Close();
delete []pBuffer;
pHttpFile->Close();
delete pHttpFile;
s_pDlg->PostMessage(WM_DOWNLOADED_MESSAGE, pParam->nTotal, pParam->nIndex);
delete pParam;
return 0;
}
*/
CHttpDownload::CHttpDownload(CDownloadDlg* pDlg)
: CInternetDownload(pDlg)
//: m_strHeader("Accept: */*/r/nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows XP)/r/n")
{
}
CHttpDownload::~CHttpDownload(void)
{
}
/*
int CHttpDownload::Download(const CString& strUrl, int nThreads)
{
s_strUrl = strUrl;
DWORD nFileSize = GetFileLength(strUrl);
UINT nSegmentLength = (nFileSize + nThreads - 1) / nThreads;
for (size_t i = 0; i < nThreads; i++)
{
ThreadParam *lpParam = new ThreadParam;
//memset(lpParam, '/0', sizeof(ThreadParam));
lpParam->nTotal = nThreads;
lpParam->nIndex = i;
lpParam->nStart = nSegmentLength * i;
lpParam->nEnd = lpParam->nStart + nSegmentLength - 1;
if (lpParam->nEnd >= nFileSize)
lpParam->nEnd = nFileSize - 1;
AfxBeginThread(ServerWorkerThread, static_cast<LPVOID>(lpParam), THREAD_PRIORITY_NORMAL, 0, 0, NULL);
//CreateThread(NULL, 0, ServerWorkerThread, (LPVOID)i, 0, 0);
}
return 0;
}
*/
(shuizhiyun) |