FTP伺服器專案的一些整理

2021-07-10 10:24:02 字數 4027 閱讀 5657

幾個月前按照網上的教程寫了乙個ftp的伺服器,現在回頭整理一下裡面的一些知識。

ftp是檔案傳輸協議(file transfer protocol),工作在tcp/ip協議族的應用層,其傳輸層使用的是tcp協議,它是基於客戶/伺服器模式工作的(c/s架構),tcp/ip協議中,ftp標準命令tcp埠號為21,port方式資料埠為20。

ftp有兩種傳輸方式:ascii檔案傳輸模式和二進位制檔案傳輸模式。

ascii檔案也稱為文字檔案,ascii檔案和二進位制檔案在物理上沒有本質的區別,他們都是由一系列的位元位組成的,他們的差別僅僅在於邏輯之上,或者說系統對他們的解析方法不同。ascii檔案由ascii字元構成,乙個ascii字元有7個位元位,最高位總是0,而二進位制檔案的最高位有可能就是1。另乙個差別是換行符,不同系統對換行符的表示方式不同,windows下換行符是\r\n,linux下的換行符是\n,其他的系統可能是其他的方式,ascii傳輸方式和二進位制傳輸方式在處理換行符也有所不同。

假定使用者正在拷貝的檔案包含的簡單ascii碼文字,如果在我們使用的系統是windows系統,而執行ftp伺服器的遠端機器上的系統是linux,那麼使用ascii傳輸模式會將\r\n轉為\n。反過來,如果我們使用的系統是linux系統,而執行ftp伺服器的遠端機器上的系統是windows,那麼使用ascii傳輸模式會將\n轉為\r\n。也就是說,

當檔案傳輸時ftp通常會自動地調整檔案的內容以便於把檔案解釋成另外那台計算機儲存文字檔案的格式。

使用ascii傳輸方式可能會改變我們的檔案,但是常常有這樣的情況,使用者正在傳輸的檔案包含的不是文字檔案,它們可能是程式,資料庫,字處理檔案或者壓縮檔案(儘管字處理檔案包含的大部分是文字,其中也包含有指示頁尺寸,字型檔等資訊的非列印字元)。

所以此時我們最好使用二進位制傳輸方式。使用二進位制傳輸時,在拷貝任何非文字檔案的時候ftp會逐字拷貝,不會對這些檔案進行處理。

如果在ascii方式下傳輸二進位制檔案,即使不需要也仍會轉譯。這會使傳輸稍微變慢 ,也會損壞資料,使檔案變得不能用。(在大多數計算機上,ascii方式一般假設每一字元的第一有效位無意義,因為ascii字元組合不使用它。如果你傳輸二進位制檔案,所有的位都是重要的。)如果你知道這兩台機器是同樣的,則二進位制方式對文字檔案和資料檔案都是有效的。

ftp的連線分為控制連線和資料連線,控制連線用於傳輸控制命令,是隨客戶端一同存在的,而資料連線只是短暫存在,每次要發生資料的時候才建立資料連線,資料傳輸完畢後就斷開資料連線。ftp的控制連線總是由客戶端想伺服器端發起的,而ftp資料連線的建立有兩種途徑,一種是客戶端連線到伺服器端,另一種是伺服器連線到客戶端,這分別對應著ftp的兩種工作模式:

被動模式和主動模式。主動和被動主要是針對ftp伺服器而言的,如果是ftp伺服器主動連線到客戶端則為主動模式,如果ftp伺服器被動地接受客戶端的連線請求則是被動模式。

ftp主動模式的工作過程如下:首先要建立控制連線通道,客戶端向ftp伺服器的21埠發起連線,經過3次握手建立控制連線通道,一旦控制連線通道建立之後,雙方便可以交換資訊了。在需要傳輸資料的時候,需要建立資料通道,選擇工作模式。當選擇主動模式時,客戶端通過控制連線通道傳送乙個port命令並告知伺服器資料連線通道的埠bb,然後伺服器就向客戶端的bb埠發出連線請求,建立資料連線通道,資料連線通道一旦建立,就可以進行資料的傳輸,傳輸完畢之後資料連線就會關閉掉。其示意圖如下:

ftp被動模式的工作過程如下:首先也是客戶端向伺服器端21埠發起連線,經過三次握手建立控制連線通道,

被動模式,需要進行資料傳輸的時候,客戶端要向伺服器傳送乙個pasv表示進行被動傳輸,即資料通道的建立是由客戶端向伺服器端發起的,而此時客戶端需要知道連線到伺服器的哪乙個埠,於是伺服器向客戶端傳送被動模式的埠xx,之後客戶端向伺服器的xx埠發起連線建立資料連線通道。其示意圖如下:

那麼ftp的資料連線為什麼要分為主動模式和被動模式呢?這個和nat或防火牆對主被動模式的影響有關。

nat是network address translation,表示網路位址轉換,通過nat可以將內網私有ip位址轉換為公網ip位址,一定程度上解決了公網位址不足的問題。

由於客戶端處於區域網之中,無法直接訪問公網上的伺服器,需要經過nat伺服器(中間那個)進行位址轉換。而nat有乙個特徵,如果是從內向外發起連線,則可以建立成功(nat會維護乙個ip的表目),如果是從外部發起的連線,則無法建立連線。

開始時客戶端想伺服器發起連線建立控制連線通道,接著客戶端向伺服器傳送port命令和資料通道的埠bb,欲通過主動模式建立資料連線通道,而因為實際上連到ftp伺服器的ip位址是經過nat伺服器進行轉換的,故伺服器實際上是連線到了nat伺服器的bb埠(此時nat的bb埠沒有啟用,故連線被拒絕),並且並沒有相應的條目可以找到客戶端,所以此時的主動模式時不能成功的。

解決方式可以自己在nat配置對映資訊,允許ftp伺服器連線過來。如果手工配置對映條目,那麼就必須知道ftp伺服器是哪乙個埠發起連線過來,所以ftp的主動模式發起連線的埠規定為20埠而不是動態選擇,否則nat對映的資訊會很多。

如果ftp客戶端處於nat或防火牆之後,並且使用被動連線,此時是可以連線成功的,示意圖如下圖所示,過程和之前的類似,這裡不再重複。

如果ftp伺服器處於nat或防火牆之後,在建立控制連線通道的時候,由於是客戶端向伺服器發起連線,因此需要在nat配置乙個對映條目(ftp伺服器固定是21埠),經過三次握手建立控制連線通道。若使用被動模式,則在建立資料連線通道的時候,處於外網的客戶端向處於內網的伺服器發起的連線可能建立不能成功,這個和之前的也是類似的。所以我們可以知道,當ftp伺服器處於nat或防火牆之後的被動模式可能建立不成功。

從上面的分析我們應該可以得到,ftp伺服器處於nat或防火牆之後的被動模式是可以建立成功的。如下圖所示

ftp伺服器是採用多程序的方式實現的,而且每來乙個連線,建立了兩個程序來為這個連線服務。

ftp伺服器是絕對不能採用多執行緒的。假如現在我們使用的是多執行緒的方式,此時有三個使用者(a,b,c)連線過來,則伺服器建立了三個執行緒(a,b,c)來進行處理。此時,假設三個客戶端登陸的是同乙個使用者lcw,並且a將目錄切換到a,b將目錄切換到b,c將目錄切換到c,那麼他們是會相互影響到的,因為多個執行緒是共享同乙個工作目錄的,當前執行緒對工作目錄的修改回影響到其他的執行緒,這是不允許的,所以不能採用多執行緒的方式。同時io復用也是不可以的(單執行緒,會影響其他連線)

那為什麼乙個客戶端連線過來要採用兩個程序呢?

這其實是出於一些安全性的考慮,一些許可權方面的限制。假如此時有乙個普通使用者lcw連線過來,則當前程序會更改為lcw程序,而在要使用ftp的主動模式進行資料傳輸的時候,ftp要向客戶端發起連線,ftp伺服器需要繫結乙個20埠,而lcw是乙個普通的使用者,沒有許可權進行埠的繫結,這就意味著他無法建立正常的資料通道。所以需要乙個程序nobody程序,來協助lcw程序(服務程序)。還有在其他某些操作的時候,我們不希望客戶端用擁有太大的許可權,反正某些危險的操作,因此把需要特殊許可權的操作都交由nobody程序來完成,而服務程序只是完成和客戶端的通訊。

lcw程序稱為服務程序,主要是用來實現與客戶端進行通訊,而nobody程序為協助程序,主要協助lcw程序完成一些和特殊許可權相關的操作,因而乙個連線需要使用兩個程序來服務。其程序模式如下圖所示:

一些Flex開源專案的整理

as3awss3lib 與 amazon s3 互動的 actionscript 3.0 類庫 聲音編輯類庫 為遊戲開發者整理的 as3 資料結構 一組flash遊戲開發的as3類庫。apeactionscript的模擬物理引擎api 用 as3 實現的密碼系統類庫,支援的演算法主要包括 rsa,a...

一些Flex開源專案的整理

as3awss3lib 與 amazon s3 互動的 actionscript 3.0 類庫 聲音編輯類庫 為遊戲開發者整理的 as3 資料結構 一組flash遊戲開發的as3類庫。apeactionscript的模擬物理引擎api 用 as3 實現的密碼系統類庫,支援的演算法主要包括 rsa,a...

一些Flex開源專案的整理

as3awss3lib 與 amazon s3 互動的 actionscript 3.0 類庫 as3soundeditorlib 聲音編輯類庫 as3ds 為遊戲開發者整理的 as3 資料結構 mecheye as3 libraries 一組flash遊戲開發的as3類庫。apeactionscr...