HTTP服务器上断点下载文件

VSCode + QMT 量化交易完整解决方案! 🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。 阅读详情
从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;
}
 
ANPC三电平拓扑双脉冲试验的原理与实施 ANPC三电平拓扑因损耗低、谐波小、应力均衡而广泛应用,但其存在短、长两类换流通道,寄生电感和开关应力差异显著。短通道尖峰小、可靠性高;长通道应力严苛。因此需分别制定两套独立双脉冲测试方案,针对不同时段和器件(如T1、T5、T6、T4及对应二极管)全面考核开关特性。 阅读详情

相关推荐

【信创-k8s】银河麒麟V10国防版+鲲鹏/飞腾(arm64架构)在线/离线部署k8s1.30+kubesphere

银河麒麟作为国家核高基专项的重要成果,国防版凭借其卓越的安全性和可靠性,已成为军工领域的首选操作系统。之前我们在适配麒麟V4国防版的过程中已发现诸多安全性要求,而麒麟V10国防版在安全防护等级上又达到了更高的级别。本文将主要演示离线部署,因为军工项目基本不会出现联网场景。即使在线,也可以按离线方式部署,且离线部署由于有私有仓库,不会存在镜像获取不到和丢失情况。

jiaworld的博客 730

http 协议大文件下载

响应的正文只能通过http响应消息进行传输,如果是小文件(比如小于1M)传输,则没有什么问题,直接把文件内容加载到正文进行回应即可,但如果是大文件(比如大于10M),不可能把文件内容加载到正文吧,如果更大的文件呢,100M?下载一个 19 M 的文件是可以成功的,再大的文件没有试,因为下载速度有点慢。那下载下来的文件是否有异常呢?windows上下载的,所以把这个文件拷贝到 CentOS 服务上看一下了,这两个文件经过 md5sum 后值是一样的,那我们下载的文件就是正常的。那用c++代码怎么写呢?....

tianyexing2008的博客 5618

国产平替NeuroSky?实测金牛座TGAM脑电模块,从Arduino到Python的完整数据采集指南

本文详细介绍了国产金牛座TGAM脑电模块的完整使用流程,包括硬件连接、数据采集和Python分析。通过Arduino和Python的实战案例,展示了如何从脑电波传感器获取并解析专注度、放松度等数据,适用于专注力训练和脑机接口开发。

weixin_30735745的博客 575

http协议及基于http协议的文件下载

目录 1. HTTP 协议概述 2. URL 与资源 3. HTTP报文 4. 使用Postman 获取数据 5. 基于HTTP协议的文件下载 5.1 文件整体下载 5.2 文件分段(Range)下载 5.2.1 获取文件的大小 5.2.2 下载分段文件 5.3 文件分块(chunk)下载 1. HTTP 协议概述 日常我们使用网络用得最多的无疑是在Web 浏览器(下文统...

Xanthium 2万+

三相SST固态变压器详细设计案例

本案例针对400kVA、30kHz三相固态变压器(SST)开展详细设计,核心采用输入串联输出并联(ISOP)拓扑架构(模块化多电平矩阵变换器M3C简化版),重点完成高频变压器的参数计算、绕组设计、损耗分析及液冷温升验证,同时覆盖系统级架构设计、半导体损耗估算及整机效率优化,全流程基于当前电力电子技术可行性展开。

qq_32103755的博客 3286

halcon第二讲:焊点提取

本文要完成的任务是将下图中焊点提取出来,对应于halcon例程Blob分析中的ball.hdev。 dev_open_window (0, 0, 512, 512, 'black', WindowHandle) read_image (Image, 'die_03.png') disp_continue_message (WindowHandle, 'black', 'true') sto...

qq_24946843的博客 7175

HTTP请求以及文件下载

HttpListener 是 .NET Framework 提供的用于创建 HTTP 服务器以侦听传入 HTTP请求的类。用法:HttpClientHttpClient 是 .NET Framework 提供的用于发送 HTTP 请求的类。它可以用于向服务器发送 GET、POST等类型的请求,并处理服务器的响应。

m0_52550458的博客 3488

EMC原理-传导(共模、差模)与辐射(近场、远场)详解

本文深入介绍了电磁兼容(EMC)的基本概念,包括EMI和EMS,以及如何处理传导干扰(共模、差模)和辐射干扰(近场、远场)。详细讨论了近场感应、远场辐射的原理,滤波器和屏蔽技术在抑制噪声信号中的作用。此外,探讨了差模和共模干扰的来源、影响及滤除方法,如使用差模电感、电容和共模线圈。最后,提到了穿心电容在滤除高频噪声中的应用。

让你爱上电路设计 3551

JAVA通过HTTP协议下载网络文件

分享一个通过原生的Java代码下载网络资源文件方法,使用URL类连接上网络服务器通过多线程使用I/O流的方式下载文件。原文链接:https://blog.youkuaiyun.com/m0_60499221/article/details/128531947。版权声明:本文为优快云博主「邻家小妹妹」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。下载线程与服务器建立连接,获取到对应的I/O流,将传入的字节写入到下载的本地文件中。启动下载任务线程,传入线程号等参数。

chuyouyinghe的专栏 2165

基于多智能体的自动化公司调研系统

在当今竞争激烈的商业世界中,了解公司的详细信息对于投资者、合作伙伴和研究机构等具有重要意义。传统的公司调研方式往往需要耗费大量的人力、物力和时间,且容易出现信息不全面、不准确等问题。基于多智能体的自动化公司调研系统的目的是利用多智能体技术,实现公司调研的自动化和智能化,提高调研的效率和准确性。本系统的范围涵盖了公司基本信息收集、市场竞争力分析、财务状况评估等多个方面。本文将按照以下结构进行组织:首先介绍系统的核心概念和相关联系,包括多智能体系统的原理和架构;

架构师的AI之路,分享AI应用开发架构的学习与实践。 964

从点击图标到Activity亮屏:AMS、Zygote、ActivityThread的Binder协作之旅

Launcher通过Context调用 startActivity(),最终会通过 Activity.startActivity() 传递到 ActivityManager.getService(),获取AMS的Binder代理对象(IActivityManager)。这里的 attach() 方法通过Binder调用AMS的 attachApplication(),将新进程的 IApplicationThread 代理对象传递给AMS。这一步的Binder通信,是整个启动流程的关键转折点,值得细细品味。

大模型大数据攻城狮的专栏 1071

JAVA用http协议实现简单文件下载

用http协议实现一个简单的网络资源下载文件! 研究大文件断点传输的时候,梳理自己的思路,写了一个http协议的文件下载的demo,非常简单,但是能够实现! 上代码: public class FileDown { InputStream inputStream; public void Filee(){ try { //新建URL对象 ...

小轩的名古屋 4714

基于STM32设计的指纹考勤机_348

随着信息化管理需求的日益增长,传统的人工考勤方式已难以满足现代社会对高效、精准和安全的考勤管理要求。为解决这一问题,本项目设计并实现了一款基于STM32的指纹考勤机系统。该系统采用AS608指纹识别模块进行人员身份识别,ESP8266无线模块实现与上位机APP的通信,支持人员信息录入、考勤时间段设置、考勤记录保存与查询等功能。系统通过SQLite数据库存储考勤数据,并提供导出EXCEL表格功能,方便数据管理与统计分析。该系统具有高效的考勤管理能力和良好的用户交互体验,能够广泛应用于企业、学校等机构的考勤管理

525

http服务器断点下载文件

<br />http://www.cnitblog.com/wangk/archive/2005/12/31/5942.aspx

ly402609921的专栏 629

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ftpclient读取服务器文件能获得文件名文件大小0_Java实现http中的文件下载断点续传...

点击上方蓝色字体,选择“标星公众号”优质文章,第一时间送达66套java从入门到精通实战课程分享实现思路:1、创建一个下载任务类SiteInfoBean(用于记录文件保存的目录,文件下载URL,文件名)2、创建一个FileAccessI 用于随机访问文件,向文件写入内容。3、创建一个下载任务执行线程SiteFileFetch,此线程主要做如下工作接受指定 下载子线程个数首先判断下载的文件...

weixin_39652658的博客 289

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

判断Http服务器是否支持断点续传

Http服务器有很多,比如,比较著名的有Apache、Nginx等,Apache会默认开启对断点续传的支持。因此,如果直接通过Web服务器来提供文件的下载,可以不必做特别的配置,即可享受到断点续传的好处。 断点续传是在发起HTTP请求的时候加入RANGE头来告诉服务器客户端已经下载了多少字节。等所有这些请求都返回之后,再把得到的内容一块一块的拼接起来得到完整的资源。简单来说,判断服务器是否支持断点续传,看Web服务器是否支持Range请求即可。 curl -i --range 0-9https://.

积微成著 2703

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

断点续传的实现:基于HTTP协议的范围请求

🤍 前端开发工程师、技术日更博主、已过CET6🍨、23年度博客之星前端领域TOP1🕠高级专题作者、打造专栏🍚签约作者、上架课程💬 前些天发现了一个巨牛的,通俗易懂,风趣幽默,忍不住分享一下给大家。。

你若盛开,清风自来 1341

Http断点下载实简单讲解

Http文件下载的普通模式就不多说了,断点下载与普通模式不一样的是,断点下载的头信息里面增加了一个属性 ? 1 RANGE: bytes=100000- 这里RANGE代表客户端要从那个位置开始下载    而服务器返回时和普通模式不同的是: 1:多了一个属性 1 Content-Range=bytes 100000-...

ljk168的专栏 6465

http下载原理/断点续传方法

HTTP 下载原理   对于 HTTP 协议,向服务器请求某个文件时,只要发送类似如下的请求即可:     GET /Path/FileName HTTP/1.0    Host:  www.caiban.net:80     Accept: */*  User-Agent: GeneralDownloadApplication

xd_ladan的专栏 2913

.net mvc 服务器无法写入文件_Java实现 http 中的文件下载断点续传(原理与实现)...

作者:riemann_https://blog.youkuaiyun.com/riemann_/article/details/8948447101断点下载续传原理断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。打个比方,浏览器请求服务器上的一个文件时,所发出的请求如下:假设服务器域名为 www.sjtu.edu.cn文件名为 down.zip。GET /down.zip H...

weixin_42397024的博客 133

Http服务器实现文件上传与下载(四)

一、引言   欢迎大家来到和我一起编写Http服务器实现文件的上传和下载,现在我稍微回顾一下之前我说的,第一、二章说明说明了整体的HTTP走向,第三章实现底层的网络编程。接着这一章我想给大家讲的是请求获取,和响应发送的内容。这里主要讲解的响应内容,为什么?因为我们编写的是一个与浏览器交互的HTTP服务器,所以大多数的情况下我们只进行被动的应答。   这就是一种"提问--回答"的问题。其

乐云天的博客 1211

java 开源 断点续传_android 下载大文件开源包(多线程 断点续传)

端点续传其实是一个很简单的原理。需要服务器端支持才行。客户端实现很简单,就算基本的读写文件。HTTP头示例:# The first 500 bytes:Content-Range: bytes 0-499/1234# The second 500 bytes:Content-Range: bytes 500-999/1234# All except for the first 500 bytes:...

weixin_32263265的博客 204

用http协议下载文件(HttpURLConnection)java

在安卓中,http协议经常用到,可以用来做文件的下载,断点续传,分段下载等等。 下载文件的服务器会给连接上的客户端发送文件的头数据,我们可以通过以下方法得到文件的头数据: 得到结果如下图: null [HTTP/1.1 200 OK] ============ X-Cache [HIT from cache.51cdn.com] ============ Server [n

a_rookie_xiaoming的博客 3074
上一篇: 利用键盘钩子开发按键发音程序
下一篇: windows ce directshow播放视频
JamesXing
博客等级 码龄20年 30粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值