Twisted學(xué)習(xí)心得(一)

一、基本概念

  • Twisted 定義:
    Twisted 是用 Python 實(shí)現(xiàn)的基于事件驅(qū)動的網(wǎng)絡(luò)引擎框架。

  • 具有以下特點(diǎn):
    -- 可擴(kuò)展性高、基于事件驅(qū)動、跨平臺。
    --Twisted 支持許多常見的傳輸及應(yīng)用層協(xié)議,如:TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。
    --Twisted 對于其支持的所有協(xié)議都帶有客戶端和服務(wù)器的實(shí)現(xiàn)

二、Twisted架構(gòu)

  • 設(shè)計(jì)哲學(xué)
    Twisted 是一個事件驅(qū)動型的網(wǎng)絡(luò)引擎。事件驅(qū)動編程是一種編程范式,這里程序的執(zhí)行流由外部事件來決定。它的特點(diǎn)是包含一個事件循環(huán),當(dāng)外部事件發(fā)生時使用回調(diào)機(jī)制來觸發(fā)相應(yīng)的處理

  • 模型圖比較
    單線程、多線程以及事件驅(qū)動編程模型的比較

線程模型.png

注:其中灰色部分為每個任務(wù)阻塞在I/O操作上所花的 時間

從上圖可以看出:

  • 單線程
    在單線程同步模型中,任務(wù)按照順序執(zhí)行。如果某個任務(wù)因?yàn)?I/O 而阻塞,其他所有的任務(wù)都必須等待,直到它完成之后它們才能依次執(zhí)行。

  • 多線程
    線程由操作系統(tǒng)來管理,在多處理器系統(tǒng)上可以并行處理,或者在單處理器系統(tǒng)上交錯執(zhí)行。這使得當(dāng)某個線程阻塞在某個資源的同時其他線程得以繼續(xù)執(zhí)行。但多線程程序難以推斷,如果實(shí)現(xiàn)不當(dāng)就會導(dǎo)致出現(xiàn)微妙且令人痛不欲生的 bug。

  • 事件驅(qū)動
    多個任務(wù)交錯執(zhí)行,但仍然在一個單獨(dú)的線程中控制通過事件循環(huán)輪詢每個事件。不需要關(guān)心線程安全問題

三、實(shí)例呈現(xiàn)

(1)服務(wù)器的實(shí)現(xiàn)
Server.py

# coding=utf-8
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory

class SimpleProtocol(Protocol):
    def connectionMade(self):
        """客戶端連入后向客戶端發(fā)送一條消息Hello"""
        print 'success from ', self.transport.client
        self.transport.write("Hello")

    def connectionLost(self, reason):
        print self.transport.client, 'disconnected'
        print reason

    def dataReceived(self, data):
        print data

factory = Factory()
factory.protocol = SimpleProtocol

# 在9001端口進(jìn)行監(jiān)聽
reactor.listenTCP(9001, factory)
# 啟動事件循環(huán)
reactor.run()

其中SimpleProtocol是我復(fù)寫的一個Protocol.

(2)客戶端的實(shí)現(xiàn)
connection.py

# coding=utf-8
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet import reactor

class Sender(Protocol):
    def connectionMade(self):
        """連接成功后調(diào)用"""
        self.send_command()

    def send_command(self):
        """連接成功后調(diào)用他向服務(wù)端發(fā)送數(shù)據(jù)"""
        self.transport.write("hello")

    def dataReceived(self, data):
        """進(jìn)行數(shù)據(jù)的接受"""
        print "DATA", data

class BasicClientFactory(ClientFactory):
    def __init__(self, protocol):
        self.protocol = protocol
          
    def clientConnectionLost(self, connector, reason):
        print 'Lost connection: %s' % reason.getErrorMessage()

PORT = 9001
HOST = '127.0.0.1'

# 實(shí)例化工廠對象
test = BasicClientFactory(Sender)
# 連接服務(wù)器
reactor.connectTCP(HOST, PORT, test)

reactor.run()

注:我復(fù)寫了客戶端所需要的工廠ClientFactory

(3)運(yùn)行測試
先在終端上運(yùn)行Server.py等待客戶端的連入,然后重新開一個終端運(yùn)行connection.py連接服務(wù)器。
會看到客戶端和服務(wù)端各自收到了一條來自對方的hello的問候消息(如下圖所示)。

服務(wù)端.png
客戶端.png

四、代碼原理剖析
(1)

  • Factory:
    每個服務(wù)器與客戶端都會有一個工廠。他負(fù)責(zé)創(chuàng)建連接。并創(chuàng)建 protocol 對象。

  • Protocols:
    Protocols 描述了如何以異步的方式處理網(wǎng)絡(luò)中的事件。當(dāng)連接創(chuàng)建成功后,F(xiàn)actory 會創(chuàng)建一個 protocol, 由 protocol 進(jìn)行通信。

  • Transports
    Transports 代表網(wǎng)絡(luò)中兩個通信結(jié)點(diǎn)之間的連接。Transports負(fù)責(zé)描述連接的細(xì)節(jié),
    比如連接是面向流式的還是面向數(shù)據(jù)報的,流控以及可靠性。

(2)

  • Transports 實(shí)現(xiàn)了 ITransports 接口,它包含如下的方法:

    -- write方法: 以非阻塞的方式按順序依次將數(shù)據(jù)寫到物理連接上。
    -- writeSequence方法: 將一個字符串列表寫到物理連接上。
    -- loseConnection 方法:將所有掛起的數(shù)據(jù)寫入,然后關(guān)閉連接。
    -- getPeer方法: 取得連接中對端的地址信息。
    -- getHost方法: 取得連接中本端的地址信息。

  • Protocols 實(shí)現(xiàn)了 IProtocol 接口,它包含如下的方法:
    -- makeConnection方法: 在 transport 對象和服務(wù)器之間建立一條連接。
    -- connectionMade方法: 連接建立起來后調(diào)用。
    -- dataReceived方法: 接收數(shù)據(jù)時調(diào)用。
    -- connectionLost方法: 關(guān)閉連接時調(diào)用。

(3)

  • Reactor 模式:
    Twisted 實(shí)現(xiàn)了設(shè)計(jì)模式中的反應(yīng)堆(reactor)模式,這種模式在單線程環(huán)境中調(diào)度多個事件源產(chǎn)生的事件到它們各自的事件處理例程中去。Twisted 的核心就是 reactor 事件循環(huán)。Reactor 可以感知網(wǎng)絡(luò)、文件系統(tǒng)以及定時器事件。它等待然后處理這些事件。

溫馨提示:

Twisted 沒有直接發(fā)送數(shù)據(jù)的函數(shù),發(fā)送數(shù)據(jù)通過Transports 中的 write 進(jìn)行數(shù)據(jù)的發(fā)送。

部分文字參考http://blog.csdn.net/hanhuili/article/details/9389433

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容