【python】Twisted网络编程
生活随笔
收集整理的這篇文章主要介紹了
【python】Twisted网络编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Twisted
- 什么是Twisted?
- 為什么使用twisted?
- Twisted 寫TCP通信基本實例
- - TCP服務端
- - TCP客戶端
- Twisted的Deferred機制
- Why Deferred?
- Deferred TCP-ECHO客戶端實現
- - TCP client為例,
什么是Twisted?
Twisted是一種非阻塞的網絡服務器技術,通過事件循環處理、回調機制來觸發相應操作。
【相比socket通信,當有多個事件時,如果有一個事件阻塞,就都阻塞的情況。】
- 異步處理:
類似小學數學題中的給定時間任務的合理安排,比如燒水和做飯兩個任務,不用等燒完水再做飯,而是燒水中去做飯,一開始燒水,中間去做飯燒開時再管熱水。
- 📕twisted原理:
- reactor中心
- 多任務輪詢
- 暫停循環回調執行操作
為什么使用twisted?
網絡編程中,最基本的對協議的包裝為socket庫。socket通信方式如下:
Tcp協議中,服務端等待客戶端發送數據rece()才能收到,否則就在阻塞等待。客戶端也一樣要等待服務端發送。這就是阻塞IO,浪費了很多性能。
Twisted 進行改進,提出非阻塞IO,不等待回復,而是不斷輪詢看是否收到。并根據情況進行狀態切換操作,這就是異步處理.
- 因此有多個客戶端時,不用多線程實現,twisted內部單線程回調都能實現[^1]
Twisted 寫TCP通信基本實例
- 📕Twisted使用方式
- protocol中定義事件回調操作(根據需要找已有的方法即可)
- 在factory中注冊
- 開啟監聽、輪詢run
- TCP服務端
# TCP服務端 import twisted import twisted.internet.protocol import twisted.internet.reactorSERVER_PORT = 8080 # 監聽端口class Server(protocol.Protocol): # 定義好事件的回調操作程序,twisted定義的事件,根據需要找到def connectionMade(self): # 客戶端連接的時候觸發print("客戶端地址: %s" % self.transport.getPeer().host)def dataReceived(self. data): # 接收客戶端數據print("[服務端]接收到數據 : %s" % data.decode("UTF-8")) # 輸出接收到的數據self.transport.write(("[ECHO] %s" % data.decode("UTF-8")).encode("UTF-8")) # 回應class DefaultServerFactory(protocol.Factory): # 定義處理工廠類,注冊protocol = Serverdef main():reactor.listenTCP(SERVER_PORT, DefaultServerFactory()) # 服務監聽print("服務啟動完畢,等待客戶端連接。。。")reactor.run() # 事件輪詢if __name__ == "__main__":main()- TCP客戶端
import twisted import twisted.internet.protocol import twisted.internet.reactor SERVER_HOST = "localhost" # server 主機 SERVER_PORT = 8080 # server端口號class Client(protocol.Protocol): # 定義客戶端回調處理def connectionMade(self):print("服務器連接成功,可以進行數據交互,如果要結束通訊,則直接回車")self.send()def send(self): # 自定義的數據發送方法input_data = input("請輸入要發送的數據")if input_data: # 有數據輸入self.transport.write(input_data.encode("UTF-8"))else:self.transport.loseConnection() # 關閉連接class DefaultClientFactory(protocol.ClientFactory):protocol = ClientclientConnectionLost = clientConnectionFailed = lambda self, connector, reason:reactor.stop() # 只要連接失敗 就關閉reactordef main():reactor.connectTCP(SERVER_HOST, SERVER_PORT, DefaultClientFactory()) reactor.run()if __name__ == "__main__":main() connectionMade()等有的函數是Twisted定義好的方法,根據需要調用即可。從代碼中可以看出Twisted優勢:在運行多個客戶端時,相比socket,這里不需要進行并發(多線程)開發,全部執行流程都是單線程的運行模式(Python中的多線程有GIL全局鎖問題)。Twisted內部會進行單線程回調實現,只需要找到對應的事件(方法)即可
Twisted的Deferred機制
Why Deferred?
線程不被長時間占用,而是另外開啟線程執行這個長時任務,執行完告訴。
Deferred TCP-ECHO客戶端實現
- TCP client為例,
import twisted import twisted.internet.protocol import twisted.internet.defer import twisted.internet.reactor import twisted.internet.threads import time SERVER_HOST = "localhost" # server 主機 SERVER_PORT = 8080 # server端口號class DeferClient(protocol.Protocol): # 設置一個回調處理類def connectionMade(self):print("服務器連接成功,可以進行數據交互,如果要結束通訊,則直接回車")self.send()def send(self): # 自定義的數據發送方法input_data = input("請輸入要發送的數據")if input_data: # 有數據輸入self.transport.write(input_data.encode("UTF-8"))else:self.transport.loseConnection() # 關閉連接def dataReceived(self, data): # 接收服務端發送的數據content = data.decode("utf-8")threads.deferToThread(self.handle_request, content).addCallback(self.handle_success) # 開啟另一線程并用回調提示完成def handle_request(self, content): # 數據處理過程print("客戶端對服務端的數據 %s 進行處理,此處會產生1s延遲..." % content) # 處理完畢后的信息輸出time.sleep(1) # 模擬延遲return content # 返回處理結果def handle_success(self, result):print(處理完成,進行參數接收 %s" % result) # 處理完畢后的信息輸出def handle_error(self, exp):print("程序出錯,%s" % exp)class DefaultClientFactory(protocol.ClientFactory):protocol = DeferClientclientConnectionLost = clientConnectionFailed = lambda self, connector, reason:reactor.stop() # 只要連接失敗 就關閉reactordef main():reactor.connectTCP(SERVER_HOST, SERVER_PORT, DefaultClientFactory()) reactor.run()if __name__ == "__main__":main()解釋:
對數據的處理需要時間,想不只等待而是先去做別的:
因此把數據放到另一線程中進行處理,并用defer回調提示完成
import twisted.internet.threads threads.deferToThread(self.handle_request, content).addCallback(self.handle_success) # 開啟另一線程并用回調提示完成注:以上總結自b站這個視頻
總結
以上是生活随笔為你收集整理的【python】Twisted网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LINK : warning LNK40
- 下一篇: Google Glass 版本揭秘