HTTP服务器上断点下载文件 _http请求超时如何下载文件-程序员宅基地

技术标签: http服务器  path  null  buffer  vcbcbdelphi的window编程  delete  internet  

从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);
                    
                    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;
            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, 
0 0 ) )
            {
                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;
}
 
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iiprogram/article/details/2205991

智能推荐

python:输入要查找的数,若在列表中找到,则返回其下标(索引)_python编写函数,根据关键字查询列表,返回下标。-程序员宅基地

文章浏览阅读3.4k次,点赞5次,收藏8次。废话不多说,直接上代码代码如下:nums = [1, 3, 5, 8, 8, 9, 10, 14, 15, 19, 19, 20, 25, 28, 29, 35, 37, 44, 49]w = int(input('请输入要查找的数据:'))while True: if w in nums: print(f'{w}的下标为{nums.index(w)}') break else: print('找不到该数据') .._python编写函数,根据关键字查询列表,返回下标。

【bzoj3555】[Ctsc2014]企鹅QQ_一个企鹅船新体验-程序员宅基地

文章浏览阅读701次。题目描述:PenguinQQ是中国最大、最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志、群、即时通讯、相册、集市等丰富强大的互联网功能体验,满足用户对社交、资讯、娱乐、交易等多方面的需求。小Q是PenguinQQ网站的管理员,他最近在进行一项有趣的研究——哪些账户是同一个人注册的。经过长时间的分析,小Q发现同一个人注册的账户名_一个企鹅船新体验

LuaXml使用_lua操作xml格式文件-程序员宅基地

文章浏览阅读1k次。LuaXml使用版本Lua 5.3写入再读取XML操作xml = require('LuaXml')local xNewFile = xml.new()-- 一级标题xNewFile[0] = "CATALOG"--[[-- 再增加一级标题写法local describ = {"Empire Burlesque"}local price = {30}local title..._lua操作xml格式文件

数据库高级语言-开窗函数-行转列-listagg_listagg over partition-程序员宅基地

文章浏览阅读942次。一,开窗函数:为了解决复杂的子查询引入进来的,开窗函数也是对行集组进行聚合计算的,并且它返回是多个值,目前oracle db2 sqlserver都支持,但是mysql不支持1.row number() over partition by :分组排名SELECT ORDER_NUMBER, PRODUCT_TYPE, ROW_NUMBER() OVER ( PARTITION BY O..._listagg over partition

Java文本框内文字显示不同颜色、字号等属性【函数调用一键实现】_java编写多线程聊天室时改变不同信息的字体颜色-程序员宅基地

文章浏览阅读6.8k次,点赞35次,收藏8次。Hello!你好哇,我是灰小猿!最近在做聊天室相关项目的开发的时候,需要对文本框中的字体进行区别显示,但是由于JTextArea文本框属于纯文本形式的,无法对其中的文本进行不同格式的显示,所以这个时候就需要使用JTextPane文本域进行文本内容的显示了。其主要原因是:JTextPane文本域中可以设置html样式JTextArea文本框不可以设置html样式这就造成了JTextPane文本域中的内容可以根据需要自行设置属性,从而实现不同文字内容的颜色、字号等属性。通过以下函数可以直_java编写多线程聊天室时改变不同信息的字体颜色

Ubuntu 16.04无法登录图形界面_ubuntu16.04图形界面登录失败-程序员宅基地

文章浏览阅读3k次。Ubuntu 16.04无法登录图形界面0、分析个人猜测,这个问题,有可能是图形界面文件受损,或者没有安装图形界面,或者图形界面没有设置默认Ubuntu开机启动1、方法1:重装Ubuntu图形界面(1)、如果不知道是否安装了图形界面,可以通过下面指令测试出:sudo apt-get install ubuntu-desktop如果存在安装了的图形界面,那么会有信息提示(2)、卸载图形界面sudo apt-get --purge remove ubuntu-desktop上面这条命令操作_ubuntu16.04图形界面登录失败

随便推点

Linux运维之(三)Samba服务器原理及安装配置_linux操作系统samba的工作原理-程序员宅基地

文章浏览阅读1.7k次。Samba服务器原理及安装简介Samba是在Linux系统上实现SMB(Session MessageBlock)协议的一个免费软件,以实现文件共享和打印机服务共享。服务器组件samba有两个主要的进程smbd和nmbd。smbd进程提供了文件和打印服务,而nmbd则提供了NetBIOS名称服务和浏览支持,帮助SMB客户定位服务器,处理所有基于UDP的协议。安装[root@..._linux操作系统samba的工作原理

异步FIFO(verilog简单实现)_verilog 简单fifo-程序员宅基地

文章浏览阅读273次。对其他网友的代码进行了改进纠正,使代码更加完整,并用vivado2020.1进行了仿真测试源代码(不到100行):`timescale 1ns/1psmodule test #(parameter data_width =4,depth =8,addr_width=3)( wclk,rst_w,w_en,din,w_ptr, rclk,rst_r,r_en,dout,r_ptr, fifo_empty,fifo_full);input wclk,rst_w,w_en;i_verilog 简单fifo

怎样用异或查找出多出的字母_已知异或怎么求字符-程序员宅基地

文章浏览阅读2.1k次。今天刷leetcode,遇到了一道题,很有意思,就是给了俩字符串,一个A,一个B,字符串B是这样子的,先把字符串A打乱,然后随机在A中加入一个任意字母,就变成了B。问加入的是啥字母?   举个例子:   A:“abc”   B:“cbea”   那么很明显,加入的字母是e。如何求出来呢?   这里介绍一种非常简答的方法,就是使用异或。   因为字母是char类型,char类型可以当做in_已知异或怎么求字符

计算机驱动空间的c盘不足怎么办,c盘空间不足-程序员宅基地

文章浏览阅读5.7k次。c盘空间不足怎么办?尽管现在的硬盘普通都已以T记,但系统分区一般我们还是分得比较小的,电脑久用未清理时较常出现安装软件或运行程序时会提示空间不足,或磁盘空间不够的提示,那么出现c盘空间不足怎么解决呢?下面就来简单介绍一下。c盘空间不足解决一: 将页面分区文件移到其它分区1、将系统页面文件从C盘移走,该文件比较大:2、右击“计算机”,选择“属性”:3、在弹出的“系统属性”对话框中,选择“高级”选项卡..._驱动器c空间不足怎么办

CSS3各个模块详解-程序员宅基地

文章浏览阅读2.2k次。一, CSS3 盒子 阴影 属性 box- shadow 也是 CSS3 新增 的 一个 重要 属性, 用来 定义 元素 的 盒子 阴影。inset: 阴影 类型, 可选 值。 如果不 设置, 其 默认 的 投影 方式 是 外 阴影; 如果 取其 唯一 值“ inset”, 就是 给 元素 设置 内 阴影。 x- offset: 阴影水平偏移量, 其值可以是正负值。 如果取正值, 则..._css3模块包括:盒子模型、列表模块、

layui upload 上传无反应_layui upload 超时时间-程序员宅基地

文章浏览阅读5.4k次,点赞2次,收藏2次。upload.js中://防止事件重复绑定 if(options.elem.data('haveEvents')) return; …… options.elem.data('haveEvents', true);第一次render之后,button '#selectFileBtn' 会被添加属性haveEvents 值为true;下一次render,haveEvents的值依然为tru..._layui upload 超时时间

推荐文章

热门文章

相关标签