FileZilla FTP服務器源代碼分析FileZilla是一款免費而且開源的FTP工具包括FileZilla ClientFileZilla Server兩個版本FileZilla Server只提供了windows系統下的版本我們要將本地的網站網頁文件上傳到網站服務器或從服務器下載網頁文件只需FileZilla Client客戶端版本就可以了FileZilla FTP服務器源代碼分在進一步分析代碼之前先復習一下FTP協議下圖是FTP的結構圖
客戶端和服務器是通過兩個連接來進行通訊的
一個是控制連接也就是傳輸些控制命令客戶端發出FTP命令服務器給出應答例如USERPASS命令等等這個連接中FTP服務器的端 口就是熟知的端口連接是由客戶端發起的例如ftp 有一點注意用戶是通過用戶接口來操作的一般的用戶接口是指cuteFTP這些FTP客戶端或者ftpexe這種命令 行程序用戶在用戶接口使用的是ftp命令如ls get cd等這些ftp命令並不是真正與FTP服務器交互的命令這些ftp命令還需要由用戶協議解釋器翻譯成真正的ftp協議命令如USER PASS才能與服務器進行交互
一個是數據連接即真正的文件傳輸是在這個連接上進行的服務器端的數據連接端口是客戶端的數據連接端口是隨機生成的數據連接只在傳輸文件 時存在文件傳完後這個連接就斷了如果需要再次傳送文件會再次建立一個數據連接(客戶端的端口是隨機的不一定是上次的那個)數據連接的模式有兩 種一種是主動方式一種是被動方式兩者的區別在於數據連接是由誰發起
我們來看一個典型的FTP交互過程用的是windows的ftpexe程序先建立一個連接然後ls看一下文件列表用get命令下 載一個文件最後quit關閉下面d選項可以顯示交互的細節注意>開頭的行是ftp客戶端發給FTP服務器的請求個數字開頭的行是服 務器的應答如 等開頭的行
C:\>ftp d localhost
Connected to dell
FileZilla Server version beta
written by Tim Kosse (TimKosse@gmxde)
Please visit
User (dell:(none)): robert
> USER robert
Password required for robert
Password:
> PASS test
Logged on
ftp> ls
> PORT
Port command successful
> NLST
Opening data channel for directory list
Manualtxt
Transfer OK
ftp: 收到 字節用時 Seconds Kbytes/sec
ftp> get Manualtxt
> PORT
Port command successful
> RETR Manualtxt
Opening data channel for file transfer
Transfer OK
ftp: 收到 字節用時 Seconds Kbytes/sec
ftp> quit
> QUIT
Goodbye
C:\>
剛開始客戶端發出建立連接的請求
C:\>ftp d localhost // 建立連接
Connected to dell // 連接已建立
然後服務器發送歡迎信息並要求輸入用戶名
FileZilla Server version beta
written by Tim Kosse (TimKosse@gmxde)
Please visit ;
User (dell:(none)):
客戶端輸入用戶名robert然後回車
> USER robert // ftpexe生成FTP命令USER發送給服務器
服務器要求輸入密碼
Password required for robert
Password:
客戶端輸入密碼然後回車
> PASS test // ftpexe生成FTP命令PASS發送給服務器
服務器通過密碼驗證
Logged on
客戶端鍵入ls命令
ftp> ls
ftpexe生成FTP命令PORT告訴服務器客戶端的隨機端口是什麼
> PORT // 是IP地址 * + = 是隨機端口號
Port command successful // 服務器響應PORT命令
> NLST // 客戶端發出NLST命令要求列出文件列表
Opening data channel for directory list // 服務器會在端口與客戶端的端口建立數據連接傳輸數據注意ls命令的結果是在數據連接中傳輸的
Manualtxt // 只有一個文件
Transfer OK // FTP服務器響應傳輸完畢
ftp: 收到 字節用時 Seconds Kbytes/sec // FTP客戶端顯示的傳輸結果
下面客戶端要求下載Manualtxt文件
ftp> get Manualtxt
> PORT // 告訴服務器客戶端新的隨機端口 * + =
Port command successful // // 服務器響應PORT命令
> RETR Manualtxt // 告訴服務器下載Manualtxt文件
Opening data channel for file transfer // 服務器會在端口與客戶端的端口建立數據連接傳輸數據
Transfer OK // FTP服務器響應傳輸完畢
ftp: 收到 字節用時 Seconds Kbytes/sec // FTP客戶端顯示的傳輸結果
最後客戶端退出
ftp> quit
> QUIT // 發出QUIT命令
Goodbye // 服務器最後響應
仔細閱讀上面的交互過程可以發現用戶手工輸入的一個FTP命令可能會被ftpexe處理成與FTP服務器的多次交互如ls get命令
要想詳細了解FTP命令的細節可以參見FTP的RFC或者相關的資料不過由於我們閱讀源代碼的主要目的不是研究FTP細節而在於掌握高並發的網絡編程的技術所以我們只以上面這個簡單的FTP交互來看一下在代碼中這個過程是如何實現的
From:http://tw.wingwit.com/Article/os/fwq/201406/31058.html