日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【python】Twisted网络编程

發布時間:2024/3/26 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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()

解釋
對數據的處理需要時間,想不只等待而是先去做別的:

def handle_request(self, content): # 數據處理過程print("客戶端對服務端的數據 %s 進行處理,此處會產生1s延遲..." % content) # 處理完畢后的信息輸出time.sleep(1) # 模擬延遲return content # 返回處理結果

因此把數據放到另一線程中進行處理,并用defer回調提示完成

import twisted.internet.threads threads.deferToThread(self.handle_request, content).addCallback(self.handle_success) # 開啟另一線程并用回調提示完成

注:以上總結自b站這個視頻

總結

以上是生活随笔為你收集整理的【python】Twisted网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。