1. 程式人生 > >HTTP檔案斷點續傳的原理

HTTP檔案斷點續傳的原理

前幾天一個同事跑過來找我說,我們在廣告素材視訊這塊想做斷點續傳,就是這次某個視訊快取到一半,下次不用重頭開始,可以在原來停留得位置開始繼續下載.以提供更好的使用者體驗。

同時說需要我們支援吐素材地址的業務介面告訴終端最後修改時間/檔案簽名(md5),用這個用來判斷我當前要下的檔案有沒有變化,同時告訴終端檔案的Size大小.

我一細想,這個問題壓根不需要通過改變現有介面提供更多的資料來做.下面從原理實現上簡單說下:

關鍵點:

對於斷點續傳,關鍵點是兩個:

1. 終端知道當前的檔案和上一次載入的檔案是不是內容發生了變化,如果有變化,需要重新從offset 0 的位置開始下載

2. 終端記錄好上次成功下載到的offset,告訴server端,server端支援從特定的offset 開始吐資料

檔案變化感知:

前置業務介面方案:

對於關鍵點1,對於決定大部分產品的業務場景,可以通過前置業務介面解決;這裡簡單介紹一下:

對於非下載工具類的產品,如視訊APP(奇藝,優酷),視訊播放前會請求相關業務的資訊,主要返回片子叫什麼名字,主要演員等等一些列資訊,同時會返回一個對於播放最重要的資訊——播放地址。 

播放地址就是我們可以做文章的地方,如果《太子妃第一集》這個片子更新了(被廣電要求減掉某個汙的畫面),可以後端系統讓這個業務介面吐不同的播放地址/一個不同的url引數(?ver=1.1)/位置引數(#ver1.1)。這樣純天然的URL變化能純天然的讓終端認為不是同一個片子,而需要重新載入。

HTPP 標準ETAG方案:

沒有業務介面的下載工具類的如何解決呢?

下載工具類的沒有前置介面,可以使用HTTP 的ETAG來標識是否檔案已經修改。

ETAG原理:如果URL上的資源內容改變,一個新的不一樣的ETag就會被分配。用這種方法使用ETag即類似於指紋,並且他們能夠被快速地被比較,以確定兩個版本的資源是否相同。ETag的比較只對同一個URL有意義——不同URL上的資源的ETag值可能相同也可能不同,從他們的ETag的比較中無從推斷。

ETAG是HTTP的一個可選欄位,且沒有規範他的實現;實際上業內用的比較多的就是使用MD5簽名的方式來生成(linux shell md5sum)

典型用法:

server端: Nginx >1.3.3 自帶有ETAG的module , 當然同時也可以在業務程式碼裡SetHeaders加一個ETAG欄位

client端:

第一次請求時:

String etag = httpURLConnection.getHeaderField("ETag");

ETag: "b428eab9654aa7c87091e"

第二次請求(斷點續傳時):

httpURLConnection.setRequestProperty(“If-None-Match”, "b428eab9654aa7c87091e"); 

If-None-Match: "b428eab9654aa7c87091e"

如果ETag值匹配,這就意味著資源沒有改變,伺服器便會發送回一個極短的響應,包含HTTP “304 未修改”的狀態。304狀態告訴客戶端,它的快取版本是最新的,並應該使用它。

然而,如果ETag的值不匹配,這就意味著資源很可能發生了變化,那麼,一個完整的響應就會被返回,包括資源的內容,就好像ETag沒有被使用。這種情況下,客戶端可以用新返回的資源和新的ETag替代先前的快取版本。

續傳支援:

對於一個C/C++程式設計師,第一時間會得出一個系統級實現方案:

1. 客戶端傳當前的offset

2. server端seek到檔案特定的offset開始讀取往http connection吐資料

不過我們深處在一個開放方案和標準不斷完善的時代,不需要自己實現一個(這也是像我這樣的C/C++研發工程師越來越沒落的原因),來看看HTTP協議是怎麼解決這個問題的:

HTTP頭Range欄位:

Range : 用於客戶端到伺服器端的請求,可通過該欄位指定下載檔案的某一段大小,及其單位。典型的格式如: 

Range: bytes=0-499 下載第0-499位元組範圍的內容
Range: bytes=500-999 下載第500-999位元組範圍的內容
Range: bytes=-500 下載最後500位元組的內容
Range: bytes=500- 下載從第500位元組開始到檔案結束部分的內容

來個簡單粗暴的例子

curl --header "Range: bytes=0-20000" xxx.com/memcache.pdf -o part1
curl --header "Range: bytes=20001-223651" xxx.com/memcache.pdf -o part2
cat part1 part2 >> a.pdf

衍生閱讀:

相關推薦

HTTP檔案斷點原理

前幾天一個同事跑過來找我說,我們在廣告素材視訊這塊想做斷點續傳,就是這次某個視訊快取到一半,下次不用重頭開始,可以在原來停留得位置開始繼續下載.以提供更好的使用者體驗。 同時說需要我們支援吐素材地址的業務介面告訴終端最後修改時間/檔案簽名(md5),用這個用來判斷我當前要下的檔案有沒有變化,同時告訴終端檔案

IOS 下載檔案斷點原理與實現(附原始碼)

在網路狀況不好的情況下,對於檔案的傳輸,我們希望能夠支援可以每次傳部分資料。首先從檔案傳輸協議FTP和TFTP開始分析, FTP是基於TCP的,一般情況下建立兩個連線,一個負責指令,一個負責資料;而TFTP是基於UDP的,由於UDP傳輸是不可靠的,雖然傳輸速度很快,但對於普通的檔案像PDF這種,少了一個

http斷點原理

位置 解壓 md5 完成 不存在 狀態 失敗 來看 ID 這周完成了一個斷點續傳的功能。 我們的遊戲裏加載地圖的邏輯簡化而言是這樣: 1.首先用本地的md5文件校驗地圖文件(很多文件)是否完整。(中間有很多步驟,任何步驟失敗都認為地圖不完整) 2.如果完整,直接加載地圖。

java http檔案斷點

1,專案調研 因為需要研究下斷點上傳的問題。找了很久終於找到一個比較好的專案。 在GoogleCode上面,程式碼弄下來超級不方便,還是配置hosts才好,把程式碼重新上傳到了github上面。 效果: 上傳中,顯示進度,時間,百分比。 點選【Pause

http斷點原理http頭 Range、Content-Range

轉載自:http://www.liqwei.com/network/protocol/2011/886.shtml 轉載自:http://blog.csdn.net/pud_zha/article/details/7924929 所謂斷點續傳,也就是要從檔案已經下載的

11_斷點原理

哪裏 一次 多少 內存 什麽 第一個 int 多線程下載 問題 斷點續傳得把下載到的位置給它記錄下來。通過什麽記?記在哪裏?記在內存裏行不行?用迅雷下了藍光電影,動輒就好幾個GB.下了一個GB突然間改早了沒網了,這個時候你放在內存裏面電腦一關所有的內容就都沒有了,下一次還得

【飛秋教程】檔案斷點

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

(QT) C++ 版本IM通訊軟體(客戶端+伺服器文字聊天、檔案斷點、線上使用者搜尋)

緊接著上一節課程,這次的作業是要求實現一個簡易版的“QQ”,可支援“軟體需求”所列出的功能。當時由於圖方便便選擇了QTCPSocket進行整個過程的通訊(事後才知道有多坑)。服務端介面比較簡單,就幾個按鈕一個進度條,主要在客戶端實現了基本的功能和介面。整個學習和

阿里雲OSS單檔案斷點+前端 簡單展示(springmvc架構)

業務沒有需要多檔案一起上傳,所以這裡只是單檔案,多檔案的話也是在獲得File的地方變成List即可,多個迴圈,多一些執行緒,網上有程式碼 一、pom.xml <dependencys> <dependenc

Android 實現多執行緒下載檔案+斷點

                            Android 多執行緒下載檔案+斷點續傳       在專案快要結束的時候,發現了app沒有版本更新的功能,於是找到一些過去的資料,在app上應用完成了版本更新,現在記錄一下apk的下載,也就是如何通過多執行緒將ap

java檔案斷點的簡單實現

import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.aw

關於ftp和http下載斷點

FTP下載斷點續傳import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; i

一分鐘實現多檔案斷點——斷點框架

本人先前的部落格有對多檔案分段斷點續傳的功能進行詳細的介紹,如果你有興趣可以先閱讀Android多檔案斷點續傳(一)——資料封裝以及介面實現。本人在先前的基礎上對程式碼進行了封裝,本帖主要介紹如何整合封裝好的框架快速實現多檔案分段斷點續傳功能。 先看效果圖

springmvc mybatis fileupload實現檔案斷點

為什麼要斷點續傳:在傳輸較大檔案沒傳輸完成時若出現斷網或者伺服器異常等情況則檔案會上傳失敗,使用者需要重新開始上傳檔案,這樣會使使用者體驗十分不好,所以需要有斷點續傳。斷點續傳好的方法是將檔案分為N個片段進行上傳,這樣即使後面的片段還未上傳完畢之前已上傳的片段也會得以保留。

HttpURLConnection實現檔案斷點

首先 client端: [java] view plain copy print? HttpURLConnection conn = null;          BufferedInputStream fin = null;          Buffere

webUploader大檔案斷點學習心得

一、準備材料:Uploader.swf、webuploader.css、webuploader.js,其中Uploader.swf只在初始化webUploader時用到,其餘兩個檔案在頁面引用即可。下載地址:https://github.com/fex-team/webup

android FileInputStream分段讀取檔案 斷點

final Thread thread = new Thread() { @Override public void run() { try {

檔案斷點

win10 node: v8.2.1 npm: v5.3.0 multer: v1.3.0 使用 1.由於對multer v1.3.0做了修改,所以不可以通過npm install multer這種形式,需要使用到修改過multer包去覆蓋原來的。 2

stream外掛跨域大檔案斷點實戰+自定義限速

JAVA跨域大檔案斷點續傳+自定義限速 前言:本文所講到的內容完全獨創,遇坑很多,但是本著資源共享的原則,將兩個星期的成果分享給大家,請尊重別人的勞動成果,轉載請註明出處:http://blog.c

Seafile深入學習(九) 之 web檔案斷點和 NFS共享

Seafile的檔案斷點續傳:原理是這樣的,你上傳一個大檔案因為某種原因中斷了上傳(可能是網路原因或者什麼),Seafile會記住中斷的位置,然後你必須重新上傳這個檔案到同一個目錄,然後伺服器會告訴你從哪裡開始上傳。這裡有一些限制:1.檔案更新和資料夾上傳不支援斷點續傳。檔案