//下载文件szFileURL从nStart开始nLen字节,下载内容用ppIResult带回
ENetRequestResult CFileTransfer::DownloadFile(const char* szFileURL, unsigned int nStart, unsigned int nLen, IMemBlock** ppIResult)
{
//参数查错
if( (!szFileURL) ¦ ¦ (!nLen) ¦ ¦ (!ppIResult) )
{
return ENRR_InvalidParam;
}
try
{
//初始化当前线程COM
CAutoInitCOM _COMAutoIniter;
//申请内存块对象
std::auto_ptr <CMemBlock > pMemBlock(new CMemBlock);
if( !pMemBlock.get() ) return ENRR_AllocMem;
if( !pMemBlock- >Resize(nLen) ) return ENRR_AllocMem;
//解析URL
const CSampleURL url(szFileURL);
//创建“连接”对象
std::auto_ptr <CHttpConnection > pConnection( m_pSession- >GetHttpConnection(url.GetHostAddr(), url.GetPort()) );
if( !pConnection.get() ) return ENRR_NetErr;
//创建“file”对象
std::auto_ptr <CHttpFile > pFile;
{
static const char* ppAccept[] = {"*/*", NULL};
pFile = std::auto_ptr <CHttpFile >(
pConnection- >OpenRequest(
CHttpConnection::HTTP_VERB_GET,
url.GetObject(),
NULL,
1,
ppAccept,
NULL,
INTERNET_FLAG_RELOAD ¦ INTERNET_FLAG_DONT_CACHE
)
);
}
if( !pFile.get() ) return ENRR_NetErr;
//添加http请求头,指示下载的部分
{
CString strHeader;
strHeader.Format("Range:bytes=%u-\r\n", nStart);
VERIFY( pFile- >AddRequestHeaders(strHeader, HTTP_ADDREQ_FLAG_REPLACE ¦ HTTP_ADDREQ_FLAG_ADD) );
}
//发送请求
if( !pFile- >SendRequest() ) //!在小猫拨号上网的条件下,这里会等待很长时间,我进去跟踪了一下实际是(::HttpSendRequest)等了很长时间
{
return ENRR_NetErr;
}
//判断服务器回应码
if( !IsHttpServerResponseSucceed(*pFile) )
{
return ENRR_NetErr;
}
//下载数据
UINT nDownloaded = 0; //已下载
for(;;)
{
const UINT nReadLen = pFile- >Read(((BYTE*)pMemBlock- >GetAddr()) + nDownloaded, pMemBlock- >GetSize() - nDownloaded);
if( !nReadLen ) break; //读完了
nDownloaded += nReadLen;
}
assert( nDownloaded <= pMemBlock- >GetSize() );
if( nDownloaded < pMemBlock- >GetSize() )
{
pMemBlock- >Resize( nDownloaded );
}
//别忘了对象是要交给Caller去管理的
*ppIResult = pMemBlock.release();
}
catch(CInternetException* e)
{
char buf[1024];
e- >GetErrorMessage(buf, sizeof(buf)); //!在小猫拨号上网的条件下,这在里总会是”操作超时”
TRACE("%s\n", buf);
e- >Delete();
return ENRR_NetErr; //WinInet异常
}
catch()
{
assert( !"未知异常!" );
return ENRR_NetErr;
}
return ENRR_Ok;
}
ENetRequestResult CFileTransfer::DownloadFile(const char* szFileURL, unsigned int nStart, unsigned int nLen, IMemBlock** ppIResult)
{
//参数查错
if( (!szFileURL) ¦ ¦ (!nLen) ¦ ¦ (!ppIResult) )
{
return ENRR_InvalidParam;
}
try
{
//初始化当前线程COM
CAutoInitCOM _COMAutoIniter;
//申请内存块对象
std::auto_ptr <CMemBlock > pMemBlock(new CMemBlock);
if( !pMemBlock.get() ) return ENRR_AllocMem;
if( !pMemBlock- >Resize(nLen) ) return ENRR_AllocMem;
//解析URL
const CSampleURL url(szFileURL);
//创建“连接”对象
std::auto_ptr <CHttpConnection > pConnection( m_pSession- >GetHttpConnection(url.GetHostAddr(), url.GetPort()) );
if( !pConnection.get() ) return ENRR_NetErr;
//创建“file”对象
std::auto_ptr <CHttpFile > pFile;
{
static const char* ppAccept[] = {"*/*", NULL};
pFile = std::auto_ptr <CHttpFile >(
pConnection- >OpenRequest(
CHttpConnection::HTTP_VERB_GET,
url.GetObject(),
NULL,
1,
ppAccept,
NULL,
INTERNET_FLAG_RELOAD ¦ INTERNET_FLAG_DONT_CACHE
)
);
}
if( !pFile.get() ) return ENRR_NetErr;
//添加http请求头,指示下载的部分
{
CString strHeader;
strHeader.Format("Range:bytes=%u-\r\n", nStart);
VERIFY( pFile- >AddRequestHeaders(strHeader, HTTP_ADDREQ_FLAG_REPLACE ¦ HTTP_ADDREQ_FLAG_ADD) );
}
//发送请求
if( !pFile- >SendRequest() ) //!在小猫拨号上网的条件下,这里会等待很长时间,我进去跟踪了一下实际是(::HttpSendRequest)等了很长时间
{
return ENRR_NetErr;
}
//判断服务器回应码
if( !IsHttpServerResponseSucceed(*pFile) )
{
return ENRR_NetErr;
}
//下载数据
UINT nDownloaded = 0; //已下载
for(;;)
{
const UINT nReadLen = pFile- >Read(((BYTE*)pMemBlock- >GetAddr()) + nDownloaded, pMemBlock- >GetSize() - nDownloaded);
if( !nReadLen ) break; //读完了
nDownloaded += nReadLen;
}
assert( nDownloaded <= pMemBlock- >GetSize() );
if( nDownloaded < pMemBlock- >GetSize() )
{
pMemBlock- >Resize( nDownloaded );
}
//别忘了对象是要交给Caller去管理的
*ppIResult = pMemBlock.release();
}
catch(CInternetException* e)
{
char buf[1024];
e- >GetErrorMessage(buf, sizeof(buf)); //!在小猫拨号上网的条件下,这在里总会是”操作超时”
TRACE("%s\n", buf);
e- >Delete();
return ENRR_NetErr; //WinInet异常
}
catch()
{
assert( !"未知异常!" );
return ENRR_NetErr;
}
return ENRR_Ok;
}