收藏 分销(赏)

HTTP服务器上断点下载文件.doc

上传人:仙人****88 文档编号:12012048 上传时间:2025-08-27 格式:DOC 页数:17 大小:55.50KB 下载积分:10 金币
下载 相关 举报
HTTP服务器上断点下载文件.doc_第1页
第1页 / 共17页
HTTP服务器上断点下载文件.doc_第2页
第2页 / 共17页


点击查看更多>>
资源描述
HTTP服务器上断点下载文件  从HTTP服务器上下载一个文件有很多方法,“热心”的微软提供了 WinInet 类,用起来也很方便。当然,我们也可以自己实现这些功能,通过格式化请求头很容易就能实现断点续传和检查更新等等功能 。 1. 连接主机 2. 格式化请求头 3. 设置接收,发送超时             要想从服务器下载文件,首先要向服务器发送一个请求。HTTP 请求头由若干行字符串组成。下面结合实例说说 HTTP 请求头的格式。假设要下载 这个网页 ,那么请求头的写法如下: 第1行:方法,请求的内容,HTTP协议的版本 下载一般可以用GET方法,请求的内容是“/index.html”,HTTP协议的版本是指浏览器支持的版本,对于下载软件来说无所谓,所以用1.1版 “HTTP/1.1”; “GET /index.html HTTP/1.1” 第2行:主机名,格式为“Host:主机” 在这个例子中是:“Host:” 第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: 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] 
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服