什么是Twisted
Twisted是一個用python語言寫的事件驅動網絡框架,它支持很多種協議,包括UDP,TCP,TLS和其他應用層協議,比如HTTP,SMTP,NNTM,IRC,XMPP/Jabber。
一個Twisted程序由reactor發起的主循環和一些回調函數組成。當事件發生了,比如一個client連接到了server,這時候服務器端的事件會被觸發執行。
官方的簡單例子啟動Twisted:
from twisted.internet import reactor def hello(): print('Hello from the reactor loop!') print('Lately I feel like I\'m stuck in a rut.') # 將函數hello傳入reactor reactor.callWhenRunning(hello) print('Starting the reactor.') # 啟動reactor后調用hello函數 reactor.run()
退出Twisted:
from twisted.internet import reactor class Countdown(object): counter=5 def count(self): if self.counter==0: # 停止reactor的循環監聽 reactor.stop() else: print(self.counter,"...") self.counter-=1 # 注冊一個回調函數第一個參數是幾秒回調,第二個參數是回調函數 reactor.callLater(1,self.count) reactor.callWhenRunning(Countdown().count) print("start") reactor.run() print("stop!") #執行結果 start 5 ... 4 ... 3 ... 2 ... 1 ... stop!
twisted中出現異常,程序並不會崩潰:
from twisted.internet import reactor # 異常函數 def falldown(): raise Exception('I fall down.') # 重啟函數 def upagain(): print('But I get up again.') # 注銷stop,程序會繼續執行,並不會崩潰,說明twisted的健壯性 reactor.stop() reactor.callWhenRunning(falldown) reactor.callWhenRunning(upagain) print('Starting the reactor.') reactor.run()
用Twisted寫一個簡單的TCP服務器
下面的代碼是一個TCPServer,這個server記錄客戶端發來的數據信息。
import sys from twisted.internet.protocol import ServerFactory from twisted.protocols.basic import LineReceiver from twisted.python import log from twisted.internet import reactor class CmdProtocol(LineReceiver): # 分隔符 delimiter = "\n" # 連接成功事件,可重載 def connectionMade(self): # 獲取客戶端的ip # getPeer獲取客戶端信息 # getHost獲取服務端信息 self.client_ip=self.transport.getPeer().host# 日志記錄來訪客戶端的ip log.msg("Client connection from %s" % self.client_ip) # 如果連接的客服端數量大於最大連接數,那么就關閉連接 if len(self.factory.clients)>=self.factory.clients_max: log.msg("Too many connections. bye !") self.client_ip=None # 關閉連接 self.transport.loseConnection() else: self.factory.clients.append(self.client_ip) # 連接斷開事件,可重載,依靠reason區分斷開類型 def connectonLost(self,reason): log.msg('Lost client connection. Reason: %s' % reason) if self.client_ip: self.factory.clients.remove(self.client_ip) # 繼承父類的方法,用於分發事件,不要重載 def lineReceived(self, line): log.msg('Cmd received from %s : %s' % (self.client_ip, line)) class MyFactory(ServerFactory): # 指向一個協議類,我們自定義的 protocol = CmdProtocol def __init__(self,clients_max=10): self.clients_max=clients_max self.clients=[] # 配置將日志輸出到stdout log.startLogging(sys.stdout) reactor.listenTCP(9999,MyFactory(2)) reactor.run()
#在cmd中輸入:
Telnet 127.0.0.1 9999 測試