0 前言:
ftp用戶端相信大家都用過,那麼我們為什麼還要用Python寫ftp用戶端呢。
我想有兩個原因:
一是寫出更好的ftp用戶端應用程式,方便大家使用;
二是定製一些特殊服務,例如每天定時下載/上傳某檔案;
我還沒能力也沒時間寫出ftp用戶端應用程式,前期先分析一下python寫ftp用戶端的核心部分,即實現上傳和下載的關鍵區段。
首先看一下ftp伺服器/用戶端架構: 1 FTP伺服器/用戶端
上圖展示了ftp的工作流程:
1.用戶端串連遠程主機上的FTP 伺服器。
2.用戶端輸入使用者名稱和密碼(或“anonymous”和電子郵件地址)。
3.用戶端進行各種檔案傳輸和資訊查詢操作。
4.用戶端從遠程FTP 伺服器退出,結束傳輸。
下面是一段Python虛擬碼。
from ftplib import FTPf = FTP('some.ftp.server')f.login('anonymous', 'your@email.address'):f. quit()
當然,這隻是一般情況下的流程。有時,由於網路兩邊電腦的崩潰或網路的問題,會導致整個傳輸在完成之前就中斷。
如果用戶端超過15 分鐘(900 秒)還沒有響應,FTP 串連就會逾時並中斷。
在底層,FTP 只使用TCP,而不使用UDP。
另外,可以將FTP 看作用戶端/伺服器編程中的特殊情況。因為這裡的用戶端和伺服器都使用兩個通訊端來通訊:
一個是控制和命令連接埠(21 號連接埠),另一個是資料連接埠(有時是20 號連接埠),如上圖 所示。
FTP 有兩種模式:主動和被動。只有在主動模式下伺服器才使用資料連接埠。
在伺服器把20 號連接埠設定為資料連接埠後,它“主動”串連用戶端的資料連接埠。而在被動模式下,伺服器只是告訴用戶端隨機的資料連接埠號碼,用戶端必須主動建立資料連線。 2 用戶端FTP 程式樣本
#!/usr/bin/env python# coding=utf-8import ftplibimport osimport socketimport pdbHOST = 'ftp.debian.org'DIRN = 'debian/tools'FILE = 'loadlin.exe'def main(): try: f = ftplib.FTP(HOST) except (socket.error, socket.gaierror) as e: print 'ERROR: cannot reach "%s"' % HOST return print '*** Connected to host "%s"' % HOST try: f.login() except ftplib.error_perm: print 'ERROR: cannot login anonymously' f.quit() return print '*** Logged in as "anonymous"' try: f.cwd(DIRN) except ftplib.error_perm: print 'ERROR: cannot CD to "%s"' % DIRN f.quit() return print '*** changed to "%s" folder' % DIRN try: f.retrbinary('RETR %s' % FILE, open(FILE,'wb').write) except ftplib.error_perm: print 'ERROR: cannot read file "%s"' % FILE os.unlink(FILE) else: print '*** Download "%s" to CWD' %FILE f.quit()if __name__ == '__main__': main()
運行結果:
3 疑問
上面編寫的用戶端代碼對ftp.debian.org網站可以正常串連,為什麼有的ftp伺服器明明可以ping通卻無法串連。
然而,卻無法串連到伺服器:
請高人指點。。謝謝。。