在網絡狀況不好的情況下,對于檔案的傳輸,我們希望能夠支援可以每次傳部分資料。首先從檔案傳輸協定FTP和TFTP開始分析,
FTP是基于TCP的,一般情況下建立兩個連接配接,一個負責指令,一個負責資料;而TFTP是基于UDP的,由于UDP傳輸是不可靠的,雖然傳輸速度很快,但對于普通的檔案像PDF這種,少了一個位元組都不行。本次以IM中的檔案下載下傳場景為例,解析基于TCP的檔案斷點續傳的原理,并用代碼實作。
什麼是斷點續傳?
斷點續傳其實正如字面意思,就是在下載下傳的斷開點繼續開始傳輸,不用再從頭開始。是以了解斷點續傳的核心後,發現其實和很簡單,關鍵就在于對傳輸中斷點的把握,我就自己的了解畫了一個簡單的示意圖:
原理:
斷點續傳的關鍵是斷點,是以在制定傳輸協定的時候要設計好,如上圖,我自定義了一個互動協定,每次下載下傳請求都會帶上下載下傳的起始點,這樣就可以支援從斷點下載下傳了,其實HTTP裡的斷點續傳也是這個原理,在HTTP的頭裡有個可選的字段RANGE,表示下載下傳的範圍,下面是我用JAVA語言實作的下載下傳斷點續傳示例。
提供下載下傳的服務端代碼:
下載下傳的用戶端代碼:
測試
原檔案、下載下傳中途斷開的檔案和從斷點下載下傳後的檔案分别從左至右如下:
斷點前的傳輸進度如下(中途省略):
Client fileLength : 51086228
finish : 0.020044541 %
finish : 0.040089082 %
finish : 0.060133625 %
finish : 0.07430574 %
finish : 0.080178164 %
...
finish : 60.41171 %
finish : 60.421593 %
finish : 60.428936 %
finish : 60.448982 %
finish : 60.454338 %
斷開的點計算:30883840 / 51086228 = 0.604543361471119 * 100% = 60.45433614%
從斷點後開始傳的進度(中途省略):
Client startIndex : 30883840
finish : 60.474377 %
finish : 60.494423 %
finish : 60.51447 %
finish : 60.53451 %
finish : 60.554558 %
finish : 99.922035 %
finish : 99.942085 %
finish : 99.95677 %
finish : 99.96213 %
finish : 99.98217 %
finish : 100.0 %
finished!
斷點處前後的百分比計算如下:
============================下面是從斷點開始的進度==============================
本方案是基于TCP,在本方案設計之初,我還探索了一下介于TCP與UDP之間的一個協定:UDT(基于UDP的可靠傳輸協定)。
我基于Netty寫了相關的測試代碼,用Wireshark拆包發現的确是UDP的包,而且是要建立連接配接的,與UDP不同的是需要建立連接配接,所說UDT的傳輸性能比TCP好,傳輸的可靠性比UDP好,屬于兩者的一個平衡的選擇,感興的可以深入研究一下。