一,最重要的一點,斷點續傳須要服務器的支持,這個是必要條件。
傳統的FTP SERVER是不支持斷點續傳的,由於它不支持REST指令,傳統的FTP指令(我是指服務器端指令)並不包括REST指令。
第二,客戶端要知道使用REST等一系列指令來做斷點續傳。
看看斷點續傳的詳細過程(FTP SERVER):
首先客戶端使用REST指令來告訴FTP SERVER它須要從文件的某個點開始傳,接着用STOR或者RETR命令開始傳文件,大概的命令的流程以下:
TYPE I
200 Type set to I.
PASV
227 Entering Passive Mode (204,48,18,69,98,250)
REST 187392
350 Restarting at 187392. Send STORE or RETRIEVE to initiate transfer.
RETR /pub/audio/pci/maestro-3/win2k/1056.zip
150 Opening BINARY mode data connection for /pub/audio/pci/maestro-3/win2k/1056.zip (936098 bytes).
首先使用TYPE命令告訴FTP SERVER使用BINARY模式傳送文件;
而後使用PASV命令告訴FTP SERVER使用被動打開模式來傳送文件;
接着使用REST 187392指令告訴FTP SERVER要從文件的187392字節開始傳送;
最後使用RETR指令來傳送文件。
從上面能夠看出,這個FTP SERVER支持REST指令,有的FTP SERVER(特別的老的)是不支持這個指令的,這時即便FTP CLIENT支持斷點續傳也一點用都沒有!
支持斷點的FTP SERVER:Serv-U FTP,還有一系列的新出現的FTP SERVER;
不支持斷點的:IIS4之前版本所帶的都不行,IIS5 有,不家能夠測試一下,登陸進FTP SERVER,而後輸入REST 1000命令,看服務器是否定識,認識就是支持斷點。服務器
FTP實現斷點續傳併發
FTP客戶端實現要創建兩個通道,一個控制命令通道,讓FTP服務器知道客戶端要幹什麼,一個數據傳輸通道。所謂的兩個通道只不過是兩個調用了connect函數的鏈接,只是控制命令通道專門用來傳輸一些字符串命令信息,而數據通道則是用來傳輸文件。控制命令通道必定是由客戶端向服務器的鏈接(默認的端口是21,也能夠指定端口,這要看服務器的設置)。鏈接的過程完成了FTP的登陸。數據通道則不必定啦,具體哪一個連哪一個,請看下面對PASV命令的解釋。 socket
其實FTP斷點續傳的原理很簡單,可分爲斷點下載和斷點上傳。 函數
客戶端的實現步驟以下: 測試
1、下載: 指針
一、向服務器發送「REST + 本地文件長度」命令,告訴服務器,客戶端要斷點下載了。這時服務器還不知道客戶端要下載哪一個文件; ip
要實現FTP的斷點續傳,FTP服務器必須支持REST指令,這條指令在FTP協議文本RFC959中就已經定義了,不過它不是FTP服務器必須支持的指令。通常,你能夠在下載前使用REST 100命令進行實驗,若是服務器正常執行了這條命令,說明該服務器支持FTP斷點續傳。REST後面跟的數表示下載文件的起始位置,而REST 0表示從文件最開始處下載。REST命令自己並不執行下載功能,你仍須要使用RETR命令執行下載工做。 ci
二、向服務器發送「RETR + 文件名」命令,通知服務器要下載的文件名,這時服務器開始定位文件指針讀文件併發送數據。 字符串
三、客戶端定位本地文件指針(文件末尾); get
四、兩端的準備工做都作完了之後,客戶端建立socket,以被動或非被動方式創建數據通道,循環調用recv接收數據並追加入本地文件;
2、上傳:
一、獲取服務器上和本地要上傳文件的同名文件大小;
二、向服務器發送「APPE + 文件名」,通知服務器,接下來從數據通道發送給你的數據要附加到這個文件末尾。
三、定位本地文件指針(和FTP上文件大小相同的位置)
四、從文件指針處讀數據併發送。
好了,FTP斷點續傳的原理就這麼簡單。代碼裏將斷點上傳和斷點下載放到同一個函數(MoveFile)裏,經過get參數說明是上傳仍是下載。固然,整個FTP類的實現有800多行,包括登陸、退出、獲取FTP文件大小、刪除FTP服務器上文件、響應服務器,解析響應信息等函數。相應的註釋代碼裏都有,這裏就不一一熬述了。
這裏重點說說PASV模式,即被動模式,這是FTP命令裏比較不容易理解的一個,這條命令請求服務器在某個端口(非FTP默認端口或控制命令端口)建立一個監聽socket,服務器建立的端口號會在客戶端的控制命令通道上獲得響應。獲得這個端口號後,客戶端就能夠建立新的socket(數據通道)connect過去,並進行文件傳輸等工做。不然,若是爲非被動模式,那麼監聽的socket由客戶端建立,服務器connect過來。
對於這條命令的存在我是這麼理解的,存在這麼一種狀況:客戶端的IP是個內網的IP,服務器的IP是個外網的,當進行數據傳輸時內網的IP對於服務器是不可見的,只有由服務器啓動監聽socket才能創建數據通道,因此必須以被動模式進行。:)