使用Python創建簡單的HTTP和FTP服務


不管工作中還是其他場合,經常會有文件分享的需求,比如自己下了一個4GB的游戲,同事下了一個800MB的軟件,其他人如果也需要這些文件,顯然直接分享是最快捷、最方便、最環保的方式了,如果再重新下,既浪費時間,又浪費電。Windows自帶了文件夾共享的功能,不過這玩意兒,至今我還沒仔細的去折騰過,也沒搞明白原理,我一直使用FTP來分享文件,如果有需要的話再弄個HTTP服務也足夠應付了,我的目的僅僅只是文件分享,簡單、易用是我主要關注的點。

反復可恥

這種需求必然是非常普遍的,解決方法也是多種多樣。比如飛鴿傳書、QQ,或者各種局域網通信軟件以及網盤都可以,不過這些都需要點對點的操作,也就是說對方需要什么文件,你就要把該文件發送過去,多一個人就需要多發一次,不能重用,對於程序員來說,不能接受,反復可恥!我覺得,文件服務器更符合這種需求,目前已經有很多成熟的軟件可以方便的實現這種需求,比如,FTP可以選擇FileZilla,HTTP可以選擇ApacheNginx。當然,成熟意味着軟件更復雜,更大的學習成本、更多磁盤占用,這要看你的需求的復雜程度。

折騰至死

好了,我需要說明,我是個喜歡折騰的人,將一件看起來復雜、學習成本高的事情,折騰到簡單、易用是我的終極愛好,這篇文章正是這種折騰后的產物,希望直接達到目的的,成熟的軟件是你最好的歸宿。喜歡折騰,換種程序員喜歡的說法是,我熱衷於把復雜的實現,隱藏在良好命名的接口下。再換種通俗點的說法,汽車內部構造精良、結構復雜,而你只需要通過操作方向盤、剎車以及油門,就可以很好的操控它,這都歸功於這些接口的友好實現。

同樣的事情,只需要一遍就好。在平時寫代碼,也是這樣。如果我需要別人提供的一個接口,那我希望這個接口使用起來盡量簡單,我只需要知道調用什么接口、傳什么參數就行。我自己寫代碼,一定嚴格按照這種思路,我不認為使用者需要關注我是如何實現的,那是我的問題,使用者需要關注的是這個接口是干什么的、需要什么參數、可能返回的結果以及可能拋出的錯誤,分工明確,減少不必要的溝通。

我在前面一遍文章中有提到Python--導出指定文件夾中as文件的完全限定類名,好處我就不多說了,一個字,性感!很巧的是,我在折騰這個文件分享的功能時,遇到了他,借着這個機會,又復習了一遍HTTP和FTP方面的內容。

Python版HTTP服務器

閑話少說,首先確保裝了Python,我裝的是2.x版本,對了,我的操作系統是WIN7,其實對於Python來說,什么操作系統並不重要。Python內置了一個簡單的HTTP服務器,只需要在命令行下面敲一行命令,一個HTTP服務器就起來了:

python -m SimpleHTTPServer 80

后面的80端口是可選的,不填會采用缺省端口8000。注意,這會將當前所在的文件夾設置為默認的Web目錄,試着在瀏覽器敲入本機地址:

http://localhost:80

如果當前文件夾有index.html文件,會默認顯示該文件,否則,會以文件列表的形式顯示目錄下所有文件。這樣已經實現了最基本的文件分享的目的,你可以做成一個腳本,再建立一個快捷方式,就可以很方便的啟動文件分享了。如果有更多需求,完全可以根據自己需要定制,具體的請參見官方文檔SimpleHTTPServer,或者直接看源碼。我拷貝一段,方便參考:

import SimpleHTTPServer
import SocketServer

PORT = 8000

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()

Python版FTP服務器

看到這里,默認你已經安裝了Python,不過你還需要安裝另外一個好用的工具。你知道,當需要找Chrome插件的時候,會去GoogleWebStore;當需要找Firefox應用的時候,會去MozillaAdd-ons;當你需要找Python組件的時候,你需要pip:A tool for installing and managing Python packages,安裝方法就不介紹了。

Python沒有內置一個直接可以用的FTP服務器,所以需要第三方組件的支持,我找到的這個組件叫pyftpdlib,首先安裝:

pip install pyftpdlib

安裝完后,和HTTP服器類似,執行以下命令就可以啟動一個FTP服務器了:

python -m pyftpdlib -p 21

后面的21端口依然是可選的,不填會隨機一個,被占用的端口將跳過。在瀏覽器敲入本機地址:

ftp://localhost:21

這時候,是匿名訪問,也就是用戶名是anonymous,密碼為空,如果想要控制訪問權限,你需要自己定制服務器,具體的可以參看pyftpdlib Tutorial,我這里拷貝過來一段作為介紹:

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

def main():
    # Instantiate a dummy authorizer for managing 'virtual' users
    authorizer = DummyAuthorizer()

    # Define a new user having full r/w permissions and a read-only
    # anonymous user
    authorizer.add_user('user', '12345', '.', perm='elradfmwM')
    authorizer.add_anonymous(os.getcwd())

    # Instantiate FTP handler class
    handler = FTPHandler
    handler.authorizer = authorizer

    # Define a customized banner (string returned when client connects)
    handler.banner = "pyftpdlib based ftpd ready."

    # Specify a masquerade address and the range of ports to use for
    # passive connections. Decomment in case you're behind a NAT.
    #handler.masquerade_address = '151.25.42.11'
    #handler.passive_ports = range(60000, 65535)

    # Instantiate FTP server class and listen on 0.0.0.0:2121
    address = ('', 2121)
    server = FTPServer(address, handler)

    # set a limit for connections
    server.max_cons = 256
    server.max_cons_per_ip = 5

    # start ftp server
    server.serve_forever()

if __name__ == '__main__':
    main()

只看代碼應該基本知道該怎么用了,add_user顯然是添加用戶,2121是指定端口,當然也可以隨機,還有最大連接數max_cons,每個ip最大連接限制,更多的接口建議直接看docstrings

后記

Python第三方組件就是個大寶庫,基本上我自己遇到的大部分問題都可以在這里面找到解決文案。同時,建議喜歡折騰的程序員,甚至沒有程序背景的IT人員,都嘗試學習一下這門語言,這對解決問題的能力以及思維的鍛煉都有莫大裨益。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM