从HTTP服务器上下载一个文件有很多方法,“热心”的微软提供了 WinInet 类,用起来也很方便。当然,我们也可以自己实现这些功能,通过格式化请求头很容易就能实现断点续传和检查更新等等功能 。
  1. 连接主机
  2. 格式化请求头
  3. 设置接收,发送超时
      

         要想从服务器下载文件,首先要向服务器发送一个请求。HTTP 请求头由若干行字符串组成。下面结合实例说说 HTTP 请求头的格式。假设要下载 http://www.sina.com.cn/index.html 这个网页 ,那么请求头的写法如下:

第1行:方法,请求的内容,HTTP协议的版本
下载一般可以用GET方法,请求的内容是“/index.html”,HTTP协议的版本是指浏览器支持的版本,对于下载软件来说无所谓,所以用1.1版 “HTTP/1.1”;
“GET /index.html HTTP/1.1”

第2行:主机名,格式为“Host:主机”
在这个例子中是:“Host:www.sina.com.cn”

第3行:接受的数据类型,下载软件当然要接收所有的数据类型,所以:
“Accept:*/*”

第4行:指定浏览器的类型
有些服务器会根据客户服务器种类的不同会增加或减少一些内容,在这个例子中可以这样写:

“User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)”

第5行:连接设置
设定为一直保持连接:“Connection:Keep-Alive”

第6行:若要实现断点续传则要指定从什么位置起接收数据,格式如下:

“Range: bytes=起始位置 - 终止位置”

比如要读前500个字节可以这样写:“Range: bytes=0 - 499”;从第 1000 个字节起开始下载:

“Range: bytes=999 -”

最后,别忘了加上一行空行,表示请求头结束。整个请求头如下:

GET /index.html HTTP/1.1
Host:www.sina.com.cn
Accept:*/*
User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)
Connection:Keep-Alive
下面用例子看看如何进行断点的下载吧






// DownloadFile.h: interface for the CDownloadFile class.
//
//
////////////////////////////////////////////////////////////////////

#
if !defined(AFX_DOWNLOADFILE_H__E9A59779_BEF9_4A78_8D0E_ED8C9498E07C__INCLUDED_)
#define AFX_DOWNLOADFILE_H__E9A59779_BEF9_4A78_8D0E_ED8C9498E07C__INCLUDED_

#
if _MSC_VER > 1000
#pragma once
#endif 
// _MSC_VER > 1000

#define NOTIFY_MSG_WPARAM_GENDOWNFILEID                
0x01

#define NOTIFY_MSG_LOW_WPARAM_FULLSIZE                
0x10
#define NOTIFY_MSG_LOW_WPARAM_CURRENTSIZE            
0x20
#define NOTIFY_MSG_LOW_WPARAM_DOWNSIZE                
0x30
#define NOTIFY_MSG_LOW_WPARAM_DOWNSPEED                
0x40

class CDownloadFile  
{
public:
    BOOL OpenRedirectHttpURL(CString 
&strOldLocation,CInternetSession &cSession);
    BOOL DownLoadFile(LPCTSTR lpFileURL,LPCTSTR lpSaveFile);
    CDownloadFile();
    virtual 
~CDownloadFile();
    LPCTSTR GetSavedFileName() { 
return m_strSaveToFile;}
    LPCTSTR GetDownURL() { 
return m_strFileURL;}

public:
    WORD GenFileID();
    
void RegisterNotifyWindow(DWORD dwThreadID,HWND hWnd,DWORD dwMsg);
    BOOL GetUNCFile();
    bool m_bForceReload;
    DWORD m_TimeOut;
    WORD m_wFileID;

protected:
    DWORD m_dwThreadID;
    
void PostNotifyMessage(WPARAM wParam, LPARAM lParam);
    DWORD m_dwMsgID;
    HWND m_hNotify;
    BOOL GetFtpFile(CInternetSession 
&cSession);
    BOOL GetHttpFile(CInternetSession 
&cSession);
    CString m_strTmpFileName;
    CString m_strFileURL;
    CString m_strSaveToFile;
    CString    m_rawHeaders;
    
float  m_transferRate;
    DWORD    m_infoStatusCode;
};

#endif 
// !defined(AFX_DOWNLOADFILE_H__E9A59779_BEF9_4A78_8D0E_ED8C9498E07C__INCLUDED_)


// DownloadFile.cpp: implementation of the CDownloadFile class.
//
//
////////////////////////////////////////////////////////////////////

#include 
"stdafx.h"
#include 
"DownloadFile.h"

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

#include 
"shlwapi.h"
#pragma comment( lib,
"shlwapi.lib" )

#ifdef _DEBUG
#undef THIS_FILE
static 
char THIS_FILE[]=__FILE__;
#define 
new DEBUG_NEW
#endif

#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()
{

}

BOOL CDownloadFile::DownLoadFile(LPCTSTR lpFileURL, LPCTSTR lpSaveFile)
{
    BOOL bRet 
= FALSE;
    
if ( !::PathIsURL(lpFileURL) )
    {
        
return bRet;
    }
    m_strSaveToFile 
= lpSaveFile;
    m_strFileURL 
= lpFileURL;
    m_strTmpFileName 
= lpSaveFile;
    m_strTmpFileName 
+= _T(".df!");
    CString strServer,strObject;INTERNET_PORT nPort;
    CString strAgentCaption 
=  _T("Update Download ") ;
    strAgentCaption 
+= ::PathFindFileName(lpSaveFile);
    DWORD dwFlags 
= 0;
    InternetGetConnectedState(
&dwFlags, 0);
    CInternetSession session (strAgentCaption, 
1,
        (dwFlags 
& INTERNET_CONNECTION_PROXY) == INTERNET_CONNECTION_PROXY ? INTERNET_OPEN_TYPE_PRECONFIG : INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
        NULL, NULL, 
0);
    AfxParseURL(m_strFileURL,dwFlags,strServer,strObject,nPort);

    
if (m_TimeOut != 0)
        session.SetOption(INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, m_TimeOut);
    
if!m_wFileID )
        m_wFileID 
= GenFileID();
    PostNotifyMessage(NOTIFY_MSG_WPARAM_GENDOWNFILEID,m_wFileID);

    
try
    {
        
if ( dwFlags== AFX_INET_SERVICE_HTTP )
        {
            bRet 
= GetHttpFile(session);
        }
        
else if( dwFlags== AFX_INET_SERVICE_FTP )
        {
            bRet 
= GetFtpFile(session);
        }
        
else if( dwFlags== AFX_INET_SERVICE_FILE )
        {
            
if( UrlIsFileUrl(m_strFileURL) )
                bRet 
= GetUNCFile();
        }
        
else
        {
            ;
        }    
    }
    
catch (CException* pEx)
    {
        TCHAR szErrorMsg[MAX_PATH] 
= {0};
        pEx
->GetErrorMessage(szErrorMsg, MAX_PATH);
        TRACE( _T(
"Exception: %s\n") , szErrorMsg);
        pEx
->Delete();
    }

    session.Close();
    m_wFileID 
= 0;
    
if (bRet)
    {
        
if (!::MoveFileEx(m_strTmpFileName,m_strSaveToFile,MOVEFILE_REPLACE_EXISTING) )
        {
            Sleep(
1000);
            ::MoveFileEx(m_strTmpFileName,m_strSaveToFile,MOVEFILE_REPLACE_EXISTING);
        }
    }
    
return bRet;
}

BOOL CDownloadFile::GetHttpFile(CInternetSession 
&cSession)
{
    BOOL bRet 
= FALSE;
    CFile m_TmpFile;
    CFileException fileException;
    
    
if ( !m_TmpFile.Open (m_strTmpFileName, 
        CFile::modeCreate 
| CFile::modeNoTruncate  | CFile::modeReadWrite
        
| CFile::shareDenyWrite    | CFile::typeBinary,
        
&fileException ) )
    {
        TRACE( _T(
"Open File failed: %d\n"), fileException.m_cause );
        
return bRet;
    }
    CString strRangeQuest;

    
if (m_TmpFile.GetLength()>0)
    {
        PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_CURRENTSIZE,m_wFileID),m_TmpFile.GetLength());
        m_TmpFile.SeekToEnd();
        strRangeQuest.Format( _T(
"%sRange: bytes=%d-\r\n"), szHeaders,m_TmpFile.GetLength());
    }
    
else
        strRangeQuest 
= szHeaders;

    DWORD dwCount 
= 0;
    CHttpFile
* pFile = NULL;
    CString strTmpURL 
= m_strFileURL;
    
try
    {
        DWORD dwFlags 
= INTERNET_FLAG_TRANSFER_BINARY 
            
|INTERNET_FLAG_DONT_CACHE
            
|INTERNET_FLAG_PRAGMA_NOCACHE
            ;
        
if (m_bForceReload) {
            dwFlags 
|= INTERNET_FLAG_RELOAD;
        }
        
//Here Find URLFile Redirect.
//
        OpenRedirectHttpURL(strTmpURL,cSession);
        pFile = (CHttpFile*) cSession.OpenURL(strTmpURL, 1, dwFlags,strRangeQuest, -1);
    }
    
catch (CInternetException* e)
    {
        TCHAR   szCause[MAX_PATH] 
= {0};
        e
->GetErrorMessage(szCause, MAX_PATH);
        e
->Delete();
        
delete pFile;
        pFile 
= NULL;
        
return bRet;
    }
    
    COleDateTime startTime 
= COleDateTime::GetCurrentTime();
    DWORD dwHttpFileSize 
= 0;
    
if (pFile)
    {
        BYTE buffer[BUFFER_SIZE
+1= {0};
        
try {
            UINT nRead 
= 0;
            pFile
->QueryInfo(HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,dwHttpFileSize);
            PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_FULLSIZE,m_wFileID),dwHttpFileSize);
            TRACE( _T(
"Totoal Length is %d\n"), dwHttpFileSize );
            dwCount 
= 0;
            
do
            {
                nRead 
= pFile->Read(buffer, BUFFER_SIZE);
                
if (nRead > 0)
                {
                    buffer[nRead] 
= 0;
                    m_TmpFile.Write(buffer,nRead);                 

                    dwCount += nRead;
                    COleDateTimeSpan elapsed = COleDateTime::GetCurrentTime() - startTime;
                    
double dSecs = elapsed.GetTotalSeconds();
                    PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSIZE,m_wFileID),dwCount);
                    
if (dSecs > 0.0)
                    {

                        m_transferRate 
= (float) ( dwCount / 1024.0 / dSecs );
                        TRACE(
"Read %d bytes (%0.1f Kb/s)\n", dwCount, m_transferRate );
                    }
                    
else
                    {
                        TRACE(
"Read %d bytes\n", dwCount);
                        m_transferRate 
= (float) ( dwCount / 1024.0 );
                    }
                    PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSPEED,m_wFileID),(LPARAM)m_transferRate);
                }
            }
            
while (nRead > 0);
            bRet 
= TRUE;
        }
        
catch (CFileException *e)
        {
            TCHAR   szCause[MAX_PATH] 
= {0};
            e
->GetErrorMessage(szCause, MAX_PATH);
            TRACE(
"ErrorMsg : %s\n", szCause);
            e
->Delete();
            
delete pFile;
            m_TmpFile.Close();
            
return FALSE;
        }
        pFile
->QueryInfoStatusCode(m_infoStatusCode);       
        pFile
->QueryInfo(HTTP_QUERY_RAW_HEADERS ,m_rawHeaders);
        pFile
->Close();
        m_TmpFile.Close();
        
delete pFile;
    }
    
    
return bRet;
}

BOOL CDownloadFile::OpenRedirectHttpURL(CString 
&strOldLocation,CInternetSession &cSession)
{
    BOOL bRet 
= FALSE;
    CHttpFile 
*pFile = NULL;
    CHttpConnection
* pServer = NULL;
    CString strServerName,strObject;
    INTERNET_PORT nPort 
= 0;
    DWORD dwServiceType 
= 0;
    
    
if (!AfxParseURL(strOldLocation, dwServiceType, strServerName, strObject, nPort) ||
        dwServiceType 
!= INTERNET_SERVICE_HTTP)
    {
        TRACE( _T(
"Not A Http Quest!\n") );
        
return bRet;
    }
    
    pServer 
= cSession.GetHttpConnection(strServerName, nPort);
    
    pFile 
= pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
        strObject, NULL, 
1, NULL, NULL, 
        INTERNET_FLAG_EXISTING_CONNECT 
| INTERNET_FLAG_NO_AUTO_REDIRECT);
    pFile
->AddRequestHeaders(szHeaders);
    pFile
->SendRequest();
    
    DWORD dwRet;
    pFile
->QueryInfoStatusCode(dwRet);
    
    
// if access was denied, prompt the user for the password
    
    
if (dwRet == HTTP_STATUS_DENIED)
    {
        DWORD dwPrompt;
        dwPrompt 
= pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
            FLAGS_ERROR_UI_FLAGS_GENERATE_DATA 
| FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);
        
        
// if the user cancelled the dialog, bail out
        
        
if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
        {
            TRACE( _T(
"Access denied: Invalid password\n") );
            
// close up the redirected site

            pFile
->Close();
            
delete pFile;
            pServer
->Close();
            
delete pServer;

            
return bRet;
        }
        
        pFile
->SendRequest();
        pFile
->QueryInfoStatusCode(dwRet);
    }
        
    
// were we redirected?
    // these response status codes come from WININET.H
    
    
if (dwRet == HTTP_STATUS_MOVED ||
        dwRet 
== HTTP_STATUS_REDIRECT ||
        dwRet 
== HTTP_STATUS_REDIRECT_METHOD)
    {
        CString strNewLocation;
        pFile
->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);
        
int nPlace = strNewLocation.Find(_T("Location: "));
        
if (nPlace == -1)
        {
            TRACE( _T(
"Error: Site redirects with no new location\n") );
            
// close up the redirected site

            pFile
->Close();
            
delete pFile;
            pServer
->Close();
            
delete pServer;
            
return bRet;
        }    
        strNewLocation 
= strNewLocation.Mid(nPlace + 10);
        nPlace 
= strNewLocation.Find('\n');
        
if (nPlace > 0)
            strNewLocation 
= strNewLocation.Left(nPlace);
        strOldLocation 
= strNewLocation;
    }
    
if ( dwRet == HTTP_STATUS_OK )
    {
        bRet 
= TRUE;
    }
    
// close up the redirected site
    pFile->Close();
    
delete pFile;
    pServer
->Close();
    
delete pServer;

    
return bRet;
}

BOOL CDownloadFile::GetFtpFile(CInternetSession 
&cSession)
{
    BOOL bRet 
= FALSE;
    CFile m_TmpFile;
    CFileException fileException;
    
    
if ( !m_TmpFile.Open (m_strTmpFileName, 
        CFile::modeCreate 
| CFile::modeNoTruncate  | CFile::modeReadWrite
        
| CFile::shareDenyWrite    | CFile::typeBinary,
        
&fileException ) )
    {
        TRACE( _T(
"Open File failed: %d\n"), fileException.m_cause );
        
return bRet;
    }

    DWORD dwCount 
= 0;
    CFtpConnection 
*pFtpConn = NULL;
    CInternetFile 
*pFile = NULL;
    
try
    {
        CString strServerName,strObject,strUserName,strPassword;
        INTERNET_PORT nPort 
= 0;
        DWORD dwServiceType 
= 0;
        CString strRestPointCommand;
    
        
if (!AfxParseURLEx(m_strFileURL, dwServiceType, strServerName, strObject, nPort, 
            strUserName, strPassword) 
||
            dwServiceType 
!= INTERNET_SERVICE_FTP)
        {
            TRACE( _T(
"Not A Ftp Quest!\n") );
        }
        
// CFtpConnection ERROR_INTERNET_NO_DIRECT_ACCESS CInternetSession
        if (strUserName.IsEmpty())
            pFtpConn 
= cSession.GetFtpConnection(strServerName,NULL,NULL,nPort,m_bForceReload);
        
else
            pFtpConn 
= cSession.GetFtpConnection(strServerName,strUserName,strPassword,nPort,m_bForceReload);
        
if (m_TmpFile.GetLength())
        {
            PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_CURRENTSIZE,m_wFileID),m_TmpFile.GetLength());
            m_TmpFile.SeekToEnd();
            strRestPointCommand.Format( _T(
"REST %d"), m_TmpFile.GetLength());
            
//strRestPointCommand.Format( _T("ls") );
            if ( !FtpCommand((*pFtpConn), FALSE, FTP_TRANSFER_TYPE_ASCII, 
            strRestPointCommand, 
00) )
            {
                TRACE( _T(
"FtpCommand failed, error: %d\n"), GetLastError());
                m_TmpFile.SeekToBegin();
            }    
        }
        
if (pFtpConn)
        {
            pFile 
= pFtpConn->OpenFile(strObject);
        }
    }
    
catch (CInternetException* e)
    {
        TCHAR   szCause[MAX_PATH] 
= {0};
        e
->GetErrorMessage(szCause, MAX_PATH);
        e
->Delete();
        
delete pFile;
        
delete pFtpConn;
        
return bRet;
    }
    
    COleDateTime startTime 
= COleDateTime::GetCurrentTime();
    DWORD dwFtpFileSize 
= 0;
    
if (pFile)
    {
        BYTE buffer[BUFFER_SIZE
+1= {0};
        
try {
            UINT nRead 
= 0;
            dwFtpFileSize 
= FtpGetFileSize( (*pFile),0);
            PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_FULLSIZE,m_wFileID),dwFtpFileSize);
            TRACE( _T(
"Totoal Length is %d\n"), dwFtpFileSize );
            dwCount 
= 0;
            
do
            {
                nRead 
= pFile->Read(buffer, BUFFER_SIZE);
                
if (nRead > 0)
                {
                    buffer[nRead] 
= 0;
                    m_TmpFile.Write(buffer,nRead);
                    
                    COleDateTimeSpan elapsed 
= COleDateTime::GetCurrentTime() - startTime;
                    
double dSecs = elapsed.GetTotalSeconds();
                    PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSIZE,m_wFileID),dwCount);
                    
if (dSecs > 0.0)
                    {
                        dwCount 
+= nRead;
                        m_transferRate 
= (float)(dwCount / 1024.0 / dSecs);
                        TRACE(
"Read %d bytes (%0.1f Kb/s)\n", dwCount, m_transferRate );                    
                    }
                    
else
                    {
                        TRACE(
"Read %d bytes\n", dwCount);
                        m_transferRate 
= (float)(dwCount / 1024.0);
                    }
                    PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSPEED,m_wFileID),(LPARAM)m_transferRate);
                }
            }
            
while (nRead > 0);
            bRet 
= TRUE;
        }
        
catch (CFileException *e)
        {
            TCHAR   szCause[MAX_PATH] 
= {0};
            e
->GetErrorMessage(szCause, MAX_PATH);
            TRACE(
"ErrorMsg : %s\n", szCause);
            e
->Delete();
            
delete pFile;
            pFtpConn
->Close();
            
delete pFtpConn;
            m_TmpFile.Close();
            
return FALSE;
        }
        pFile
->Close();
        
delete pFile;
        m_TmpFile.Close();
        pFtpConn
->Close();
        
delete pFtpConn;
    }
    
return bRet;
}

BOOL CDownloadFile::GetUNCFile()
{
    BOOL bRet 
= FALSE;
    CFile m_TmpFile,m_SrcFile;
    CFileException fileException;
    CString strOldLocation 
= m_strFileURL;
    
if ( !m_TmpFile.Open (m_strTmpFileName, 
        CFile::modeCreate 
| CFile::modeNoTruncate  | CFile::modeReadWrite
        
| CFile::shareDenyWrite    | CFile::typeBinary,
        
&fileException ) )
    {
        TRACE( _T(
"Open File failed: %d\n"), fileException.m_cause );
        
return bRet;
    }
    strOldLocation.TrimLeft();
    strOldLocation.TrimRight();
    
if( StrCmpNI(strOldLocation, _T("file:/"),6== 0 )
    {
        strOldLocation 
= strOldLocation.Mid(8);
        strOldLocation.Replace( _T('
/'), _T('\\'));
    }

    
if ( !m_SrcFile.Open ( strOldLocation, 
         CFile::modeRead 
| CFile::shareDenyWrite | CFile::typeBinary,
        
&fileException ) )
    {
        TRACE( _T(
"Open File failed: %d\n"), fileException.m_cause );
        
return bRet;
    }
    COleDateTime startTime 
= COleDateTime::GetCurrentTime();
    DWORD dwCount 
= 0;
    
try {
        
if (m_TmpFile.GetLength())
        {
            PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_CURRENTSIZE,m_wFileID),m_TmpFile.GetLength());
            m_TmpFile.SeekToEnd();
            m_SrcFile.Seek(m_TmpFile.GetLength(), CFile::begin);
        }
        BYTE buffer[BUFFER_SIZE
+1= {0};
        UINT nRead 
= 0;
        PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_FULLSIZE,m_wFileID),m_SrcFile.GetLength());
        TRACE( _T(
"Totoal Length is %d,left is %d\n"), m_SrcFile.GetLength() ,m_SrcFile.GetLength() - m_TmpFile.GetLength());
        dwCount 
= 0;
        
do
        {
            nRead 
= m_SrcFile.Read(buffer, BUFFER_SIZE);
            
if (nRead > 0)
            {
                buffer[nRead] 
= 0;
                m_TmpFile.Write(buffer,nRead);
                
                COleDateTimeSpan elapsed 
= COleDateTime::GetCurrentTime() - startTime;
                
double dSecs = elapsed.GetTotalSeconds();
                PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSIZE,m_wFileID),dwCount);
                
if (dSecs > 0.0)
                {
                    dwCount 
+= nRead;
                    m_transferRate 
= (float)(dwCount / 1024.0 / dSecs);
                    TRACE(
"Read %d bytes (%0.1f Kb/s)\n", dwCount, m_transferRate );                    
                }
                
else
                {
                    TRACE(
"Read %d bytes\n", dwCount);
                    m_transferRate 
= (float)(dwCount / 1024.0);
                }
                PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSPEED,m_wFileID),(LPARAM)m_transferRate);
            }
        }
        
while (nRead > 0);
        bRet 
= TRUE;
    }
    
catch (CFileException *e)
    {
        TCHAR   szCause[MAX_PATH] 
= {0};
        e
->GetErrorMessage(szCause, MAX_PATH);
        TRACE(
"ErrorMsg : %s\n", szCause);
        e
->Delete();
        m_TmpFile.Close();
        
return FALSE;
    }
    m_TmpFile.Close();
    
return bRet;
}

void CDownloadFile::RegisterNotifyWindow(DWORD dwThreadID,HWND hWnd, DWORD dwMsg)
{
    m_dwThreadID 
= dwThreadID;
    m_hNotify 
= hWnd;
    m_dwMsgID 
= dwMsg;
}

void CDownloadFile::PostNotifyMessage(WPARAM wParam, LPARAM lParam)
{
    
if (m_hNotify)
    {
        ::PostMessage(m_hNotify, m_dwMsgID, wParam,  lParam);
    }
    
if ( m_dwThreadID )
    {
        ::PostThreadMessage(m_dwThreadID,m_dwMsgID, wParam, lParam);
    }
}

WORD CDownloadFile::GenFileID()
{
    srand(GetTickCount());
    
return rand() & 0xFFFF;
}
UINT ThreadDownSingleFile( LPVOID pParam )
{
    CDownloadFile m_DownFile;
    UINT uRet 
= 0;
    
if (lpDownParam)
    {
        m_DownFile.m_wFileID 
= m_DownFile.GenFileID();
        
//这里注册通知窗口和消息
        //m_DownFile.RegisterNotifyWindow
        if ( m_DownFile.DownLoadFile(m_Msg.lpFileSrc, m_Msg.lpFileDst) )
        {
            uRet 
= 1;
        }
    }
    
return uRet;
}
posted on 2005-12-31 14:22 孤独的夜 阅读(9575) 评论(12)  编辑 收藏 引用 所属分类: VC Skill
Comments
  • # re: HTTP服务器上断点下载文件
    ALAN
    Posted @ 2006-02-07 16:02
    非常不错
    有没有 上传的 代码阿????
    这个比较重要!
    感谢!  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    noname
    Posted @ 2006-03-09 10:55
    session.SetOption(INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, m_TimeOut);

    MSDN上说INTERNET_OPTION_DATA_RECEIVE_TIMEOUT是没有实现的参数  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    孤独的夜
    Posted @ 2006-03-17 09:18
    你要用最新的SDK里面有。  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    QQ 308806913
    Posted @ 2006-03-21 17:04
    本人菜鸟 没能看出 断点是怎样 续传的 清高手指点一二,万分感激。。。
    QQ 308806913, C++ 群 2306581。。。 欢迎大家一起交流讨论 谢谢  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    QQ 308806913
    Posted @ 2006-03-21 17:10
    我查了很多资料, 要实现断点续传,一般都用到 CinternetFile::Seek 函数,但是我在使用的时候,弹匡,异常郁闷。。。。。!!!!!  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    QQ 308806913
    Posted @ 2006-03-21 17:22
    REST "+filesize+"\r\n";使服务器搜索服务器端的文件流到指定的断点
    看到了 ,,,,谢谢 斑竹  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    devel
    Posted @ 2007-05-22 09:08
    多谢!!!!!  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    didi
    Posted @ 2007-10-17 09:58
    太好了!!  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    阿才
    Posted @ 2007-10-22 19:07
    文章很好!顶!  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    tangxinfa
    Posted @ 2008-11-19 13:33
    在下载前应该再加上连接后的错误检测代码,以免当要下载的文件不存在时,下载文件的内容为错误信息:
    DWORD dwStatusCode;
    if(pFile->QueryInfo(HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, dwStatusCode) &&
    dwStatusCode != HTTP_STATUS_OK)
    {
    TRACE("Download error, status code: %d\n", dwStatusCode);
    return FALSE;
    }  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    idoiwill
    Posted @ 2009-10-21 09:30
    PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSIZE,m_wFileID),dwCount);
    if (dSecs > 0.0)
    {
    dwCount += nRead;
    m_transferRate = (float)(dwCount / 1024.0 / dSecs);
    TRACE("Read %d bytes (%0.1f Kb/s)\n", dwCount, m_transferRate );
    }
    应该要改成:
    dwCount += nRead;
    PostNotifyMessage(MAKEWPARAM(NOTIFY_MSG_LOW_WPARAM_DOWNSIZE,m_wFileID),dwCount);
    if (dSecs > 0.0)
    {

    m_transferRate = (float)(dwCount / 1024.0 / dSecs);
    TRACE("Read %d bytes (%0.1f Kb/s)\n", dwCount, m_transferRate );
    }
    不然在断点续传时,计算有误(算少了)  回复  更多评论   
  • # re: HTTP服务器上断点下载文件
    Liang
    Posted @ 2011-05-18 18:31
    你的断点续传似乎用不了啊  回复  更多评论   
只有注册用户登录后才能发表评论。