顧名思義斷點續傳就是在上一次下載時斷開的位置開始繼續下載在HTTP協議中可以在請求報文頭中加入Range段來表示客戶機希望從何處繼續下載
斷點續傳的原理
在了解HTTP斷點續傳的原理之前先來說說HTTP協議HTTP協議是一種基於tcp的簡單協議分為請求和回復兩種請求協議是由客戶機(浏覽器)向服務器(WEB SERVER)提交請求時發送報文的協議回復協議是由服務器(web server)向客戶機(浏覽器)回復報文時的協議請求和回復協議都由頭和體組成頭和體之間以一行空行為分隔
以下是一個請求報文與相應的回復報文的例子
GET /image/index_r_cjpg HTTP/
Accept: */*
Referer:
AcceptLanguage: zhcn
AcceptEncoding: gzip deflate
UserAgent: Mozilla/ (compatible; MSIE ; Windows NT ; NET
CLR )
Host: :
Connection: KeepAlive
HTTP/ OK
Server: MicrosoftIIS/
Date: Tue Jun :: GMT
ContentType: image/jpeg
AcceptRanges: bytes
LastModified: Thu May :: GMT
ETag: becebc:
ContentLength:
JFIF H H nbsp; C []
…
下面我們就來說說斷點續傳
顧名思義斷點續傳就是在上一次下載時斷開的位置開始繼續下載在HTTP協議中可以在請求報文頭中加入Range段來表示客戶機希望從何處繼續下載
比如說從第字節開始下載請求報文如下
GET /image/index_r_cjpg HTTP/
Accept: */*
Referer:
AcceptLanguage: zhcn
AcceptEncoding: gzip deflate
UserAgent: Mozilla/ (compatible; MSIE ; Windows NT ; NET
CLR )
Host: :
Range:bytes=
Connection: KeepAlive
NET中的相關類
明白了上面的原理那麼我們來看看NET FRAMEWORK中為我們提供了哪些類可以來做這些事
完成HTTP請求
SystemNetHttpWebRequest
HttpWebRequest 類對 WebRequest 中定義的屬性和方法提供支持也對使用戶能夠直接與使用 HTTP 的服務器交互的附加屬性和方法提供支持
HttpWebRequest 將發送到 Internet 資源的公共 HTTP 標頭值公開為屬性由方法或系統設置下表包含完整列表可以將 Headers 屬性中的其他標頭設置為名稱/值對但是注意某些公共標頭被視為受限制的它們或者直接由 API公開或者受到系統保護不能被更改Range也屬於被保護之列不過NET為開發者提供了更方便的操作就是 AddRange方法向請求添加從請求數據的開始處或結束處的特定范圍的字節范圍標頭
完成文件訪問
SystemIOFileStream
FileStream 對象支持使用Seek方法對文件進行隨機訪問 Seek 允許將讀取/寫入位置移動到文件中的任意位置這是通過字節偏移參考點參數完成的字節偏移量是相對於查找參考點而言的該參考點可以是基礎文件的開始當前位置或結尾分別由SeekOrigin類的三個屬性表示
代碼實現
了解了NET提供的相關的類那麼我們就可以方便的實現了
代碼如下
static void Main(string[] args)
{
string StrFileName=c:\\aazip; //根據實際情況設置
string StrUrl=; //根據實際情況設置
//打開上次下載的文件或新建文件
long lStartPos =;
SystemIOFileStream fs;
if (SystemIOFileExists(StrFileName))
{
fs= SystemIOFileOpenWrite(StrFileName);
lStartPos=fsLength;
fsSeek(lStartPosSystemIOSeekOriginCurrent); //移動文件流中的當前指針
}
else
{
fs = new SystemIOFileStream(StrFileNameSystemIOFileModeCreate);
lStartPos =;
}
//打開網絡連接
try
{
SystemNetHttpWebRequest request =(SystemNetHttpWebRequest)SystemNet
HttpWebRequestCreate(StrUrl);
if ( lStartPos>)
requestAddRange((int)lStartPos); //設置Range值
//向服務器請求獲得服務器回應數據流
SystemIOStream ns= requestGetResponse()GetResponseStream();
byte[] nbytes = new byte[];
int nReadSize=;
nReadSize=nsRead(nbytes);
while( nReadSize >)
{
fsWrite(nbytesnReadSize);
nReadSize=nsRead(nbytes);
}
fsClose();
nsClose();
ConsoleWriteLine(下載完成);
}
catch(Exception ex)
{
fsClose();
ConsoleWriteLine(下載過程中出現錯誤:+exToString());
}
}
From:http://tw.wingwit.com/Article/program/net/201311/13111.html