一,最重要的一點,斷點續傳需要服務器的支持,這個是必要條件。
傳統的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命令的解釋。
其實FTP斷點續傳的原理很簡單,可分為斷點下載和斷點上傳。
客戶端的實現步驟如下:
一、下載:
1、向服務器發送“REST + 本地文件長度”命令,告訴服務器,客戶端要斷點下載了。這時服務器還不知道客戶端要下載哪個文件;
要實現FTP的斷點續傳,FTP服務器必須支持REST指令,這條指令在FTP協議文本RFC959中就已經定義了,不過它不是FTP服務器必須支持的指令。一般,你可以在下載前使用REST 100命令進行實驗,如果服務器正常執行了這條命令,說明該服務器支持FTP斷點續傳。REST后面跟的數表示下載文件的起始位置,而REST 0表示從文件最開始處下載。REST命令本身並不執行下載功能,你仍需要使用RETR命令執行下載工作。
2、向服務器發送“RETR + 文件名”命令,通知服務器要下載的文件名,這時服務器開始定位文件指針讀文件並發送數據。
3、客戶端定位本地文件指針(文件末尾);
4、兩端的准備工作都做完了以后,客戶端創建socket,以被動或非被動方式建立數據通道,循環調用recv接收數據並追加入本地文件;
二、上傳:
1、獲取服務器上和本地要上傳文件的同名文件大小;
2、向服務器發送“APPE + 文件名”,通知服務器,接下來從數據通道發送給你的數據要附加到這個文件末尾。
3、定位本地文件指針(和FTP上文件大小相同的位置)
4、從文件指針處讀數據並發送。
好了,FTP斷點續傳的原理就這么簡單。代碼里將斷點上傳和斷點下載放到同一個函數(MoveFile)里,通過get參數說明是上傳還是下載。當然,整個FTP類的實現有800多行,包括登錄、退出、獲取FTP文件大小、刪除FTP服務器上文件、響應服務器,解析響應信息等函數。相應的注釋代碼里都有,這里就不一一熬述了。
這里重點說說PASV模式,即被動模式,這是FTP命令里比較不容易理解的一個,這條命令請求服務器在某個端口(非FTP默認端口或控制命令端口)創建一個監聽socket,服務器創建的端口號會在客戶端的控制命令通道上得到響應。得到這個端口號后,客戶端就可以創建新的socket(數據通道)connect過去,並進行文件傳輸等工作。否則,如果為非被動模式,那么監聽的socket由客戶端創建,服務器connect過來。
對於這條命令的存在我是這么理解的,存在這么一種情況:客戶端的IP是個內網的IP,服務器的IP是個外網的,當進行數據傳輸時內網的IP對於服務器是不可見的,只有由服務器啟動監聽socket才能建立數據通道,所以必須以被動模式進行。:)