python網絡框架Twisted


什么是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 測試

 


免責聲明!

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



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