1. 程式人生 > >HTTP檔案傳輸

HTTP檔案傳輸

        HTTP協議用於檔案傳輸時,一般把檔案內容放到訊息體中。作為TCP之上的流式傳輸協議,傳送端和接收端可以對大檔案進行流式的傳送和接收。

1.確定大小的檔案傳輸

        訊息頭部的Content-Length欄位表示檔案的長度,用於接收端確定檔案的結束。

2.Chunked編碼

        當檔案大小無法事先確定時,無法設定Content-Length欄位。此時可以用分塊傳輸的方式,將檔案分成多個部分進行傳送。在分塊傳送方式下,頭部增加Transfer-Encoding: chunked,存在這個頭部時不允許再加上Content-Length頭,即使有也會被忽略。

        Chunked模式下,訊息體分塊傳送,每一塊頭部儲存資料長度,跟上CRLF,然後是具體的資料,塊與塊之間也是CRLF分隔。當長度頭為0時,表示塊的結束。

3.使用multipart/form-data上傳檔案

        原始的POST請求訊息體中是URL編碼後的表單,格式為key=value,不同的key、value之間用&分隔。上傳二進位制的檔案時,可以用multipart/form-data的方式。

        在這種方式下,基礎的請求仍然是POST請求,檔案內容放在訊息體,只是Content-Type欄位的值為multipart/form-data,並隨機選擇一個字串作為分隔符(理論上需要這個分隔符不在檔案內容中出現,一般隨機選擇的字串出現在正文中的概率非常小,如果真的出現會導致POST失敗,需要另外發起一次請求重新選擇隨機字串),然後,每個欄位之間用”--分隔符”進行分隔,最後一個”--分隔符--”表示結束。每個欄位中都可以包含頭部和訊息體,頭部的內容可以包含檔名稱、檔案路徑等,也可以是檔案的二進位制內容本身。

4.斷點續傳與多執行緒傳輸

        這裡仍然是運用分塊傳輸的思想:如果傳輸中途中斷,接下來可以從中斷的地方重新開始避免從頭開始的浪費;在多執行緒程式中,各個執行緒可以分別負責傳輸一個檔案塊,然後將他們合併恢復成為原始檔案。

        分塊傳輸就需要確定塊的邊界,這裡採用的是Range欄位,表示從某一位元組開始,如Range:bytes=100-,表示請求的是從檔案的100位元組開始到檔案末尾,返回訊息為206 Partial Content,頭部欄位增加Content-Range: bytes100-199/200,表示返回檔案100-199位元組內容,檔案一共200位元組。

        多執行緒傳輸時,每個執行緒請求檔案中不同的range,傳輸完成後由應用作合併。