天天看點

Ftp多線程與斷點續傳

其實FTP斷點續傳的原理很簡單,可分為斷點下載下傳和斷點上傳。

      一、下載下傳:

1、向伺服器發送“REST + 本地檔案長度”指令,告訴伺服器,用戶端要斷點下載下傳了。這時伺服器還不知道用戶端要下載下傳哪個檔案;

2、向伺服器發送“RETR + 檔案名”指令,通知伺服器要下載下傳的檔案名,這時伺服器開始定位檔案指針讀檔案并發送資料。

3、用戶端定位本地檔案指針(檔案末尾);

4、兩端的準備工作都做完了以後,用戶端建立socket,以被動或非被動方式建立資料通道,循環調用recv接收資料并追加入本地檔案;

  二、上傳:

1、擷取伺服器上和本地要上傳檔案的同名檔案大小;

2、向伺服器發送“APPE +檔案名”,通知伺服器,接下來從資料通道發送給你的資料要附加到這個檔案末尾。

3、定位本地檔案指針(和FTP上檔案大小相同的位置)

4、從檔案指針處讀資料并發送。

  這裡重點說說PASV模式,即被動模式,這是FTP指令裡比較不容易了解的一個,這條指令請求伺服器在某個端口(非FTP預設端口或控制指令端口)建立一個監聽socket,伺服器建立的端口号會在用戶端的控制指令通道上得到響應。得到這個端口号後,用戶端就可以建立新的socket(資料通道)connect過去,并進行檔案傳輸等工作。否則,如果為非被動模式,那麼監聽的socket由用戶端建立,伺服器connect過來。

對于這條指令的存在我是這麼了解的,存在這麼一種情況:用戶端的IP是個内網的IP,伺服器的IP是個外網的,當進行資料傳輸時内網的IP對于伺服器是不可見的,隻有由伺服器啟動監聽socket才能建立資料通道,是以必須以被動模式進行。:)       ===========以下轉載==========

現在有不少軟體可實作多線程下載下傳.如NetAnts,JetCar等,其實多線程下載下傳的原理并不複雜,主要的兩項技術就是多線程和斷點下載下傳。程式中開啟多個線程,每個線程利用斷點下載下傳,分别下載下傳檔案的不同部分,下載下傳完後合并,就可以了。多線程程式設計很多書已有介紹,這裡不再重複,關于斷點下載下傳,MFC中提供的CInternetFile類可實作HTTP的斷點下載下傳,但無法實作FTP的斷點下載下傳。是以,我們隻好從FTP協定中的指令入手,自己編寫個FTP類,來實作多線程下載下傳。本人編寫的CMultiFTP類(在WIN2000+IIS5。0下測試成功)已在CSDN發表。

FTP指令的詳細資訊,大家可從http://info.internet.isi.edu/in-notes/rfc/處獲得,這裡給大家介紹下與多線程下載下傳有關的幾個指令極其格式:

USER〈USERNAME〉:登陸FTP的使用者名,執行成功傳回220;

PASS〈PASSWORD〉:密碼,執行成功傳回230;

REST〈POS〉:指定檔案下載下傳的開始位置,執行成功傳回350;

SIZE〈FILENAME〉:檔案大小,執行成功傳回213;

PASV:建立資料連接配接,同時取得FTP伺服器下載下傳檔案時用的端口号,執行成功傳回227;

TYPE:指定下載下傳檔案的類型,參數為I是二進制檔案,為A是字元檔案,執行成功傳回200;

RETR〈FILENAME〉:下載下傳檔案,執行成功傳回125;

這些指令中,REST,RETR,SIZE三個指令最關鍵,在後面會給大家更詳細的說明,另外執行FTP指令,FTP伺服器會向用戶端傳回一代碼,指令執行成功的代碼上面已給出。向伺服器發送指令,可把指令當作字元串向伺服器發送,如:send(socket,”rest 100/r/n”,…)(注意:要在指令後加/r/n)。

在介紹多線程下載下傳前,先給大家介紹下連接配接FTP伺服器和從FTP伺服器下載下傳檔案的過程。連接配接FTP SERVER很簡單,建立一套接字,指定伺服器的位址和端口号,連接配接到伺服器,再向它發送USER和PASS指令,伺服器傳回230,就代表登陸成功,并且伺服器和客戶建立了一控制連接配接。

FTP伺服器下載下傳檔案的過程比較複雜。首先,用戶端要和伺服器建立一資料連接配接,可用PORT或PASV指令建立資料連接配接,PORT指令要自己指定一端口号用于下載下傳,PASV指令則由伺服器配置設定一端口号,用戶端可從伺服器的傳回資訊提取端口号,傳回資訊的格式為:

(伺服器IP,端口号),本人的程式将使用PASV指令。然後向伺服器發送RETR指令下載下傳檔案,或先發送一REST指令指明從哪下載下傳檔案。之後,要建立一新的套接字,連接配接到資料連接配接指定的端口,檔案資料就從這個套接字下載下傳。下載下傳完畢後,關閉套接字。

現在進入本篇的精華,實作多線程下載下傳。執行完登陸操作後,先發送“REST 100”指令,測試下伺服器是否支援斷點下載下傳,如傳回成功代碼,就可實作多線程下載下傳;然後發送“SIZE”,取得檔案的大小,根據檔案大小,将檔案分為幾部分,記下各部分的偏移位址,并作為參數,交給各線程去下載下傳。在下載下傳線程中,先接受主線程傳給他的參數(檔案名,偏移位址,儲存位址等),再發送“PASV”指令,建立資料連接配接,并建立一套接字連接配接到新的端口;然後根據檔案類型,二進制檔案發送“TYPE  I“指令,文本檔案發送”TYPE  A“指令;之後發送“REST  〈檔案偏移位址〉”指令,通知伺服器改變将要下載下傳的檔案的開始位址;最後,執行“RETR 〈檔案名〉”指令,下載下傳檔案。下載下傳完畢後,編段代碼合并檔案即可。

在這裡有個問題,就是主線程如何得知各下載下傳線程已執行完畢。WINDOWS提供了幾種線程互斥技術,如CriticalSection,Mutex等,關于他們的詳細資訊,大家可參考各種程式設計書籍,在這裡我推薦使用CriticalSection技術。可以在程式中建立一全局計數器,在檔案下載下傳前置零,并建立一全局CriticalSection變量。在下載下傳線程中,當檔案下載下傳完畢後,先鎖定全局CriticalSection變量,之後将計數器加一,再釋放全局CriticalSection變量。主線程中,可建立一定時,定期檢查計數器的值,或讓下載下傳線程在下載下傳完畢後調用主線程的某個函數。這樣,主線程就可随時發現檔案已下載下傳完畢,可合并檔案了。

多線程下載下傳的程式設計就是這樣,一點都不難。看來掌握某些計算機技術,特别是網絡技術,最好還是從實作原理入手,掌握其最精華的部分,激發自己的靈感,編寫出個優秀軟體。老停留在使用别人的元件和函數庫的基礎上,你的水準不會有太大提高。

平台提供: http://www.kaola.cn

繼續閱讀