python3 socketserver_《Python核心编程(第3版)》——2.5 *SocketServer模块
本節書摘來自異步社區《Python核心編程(第3版)》一書中的第2章,第2.5節,作者[美] Wesley Chun(衛斯理 春),孫波翔 李斌 李晗 譯,更多章節內容可以訪問云棲社區“異步社區”公眾號查看。
2.5 *SocketServer模塊
SocketServer是標準庫中的一個高級模塊(Python 3.x中重命名為socketserver),它的目標是簡化很多樣板代碼,它們是創建網絡客戶端和服務器所必需的代碼。這個模塊中有為你創建的各種各樣的類,如表2-3所示。
通過復制前面展示的基本TCP示例,我們將創建一個TCP客戶端和服務器。你會發現它們之間存在明顯的相似性,但是也應該看到我們如何處理一些繁瑣的工作,于是你不必擔心樣板代碼。這些代表了你能夠編寫的最簡單的同步服務器(為了將你的服務器配置為異步運行,可以查看本章末尾的練習)。
除了為你隱藏了實現細節之外,另一個不同之處是,我們現在使用類來編寫應用程序。因為以面向對象的方式處理事務有助于組織數據,以及邏輯性地將功能放在正確的地方。你還會注意到,應用程序現在是事件驅動的,這意味著只有在系統中的事件發生時,它們才會工作。
事件包括消息的發送和接收。事實上,你會看到類定義只包括一個用來接收客戶端消息的事件處理程序。所有其他的功能都來自使用的SocketServer類。此外,GUI編程(見第5章)也是事件驅動的。你會立即注意到它們的相似性,因為最后一行代碼通常是一個服務器的無限循環,它等待并響應客戶端的服務請求。它工作起來幾乎與本章前面的基礎TCP服務器中的無限while循環一樣。
在原始服務器循環中,我們阻塞等待請求,當接收到請求時就對其提供服務,然后繼續等待。在此處的服務器循環中,并非在服務器中創建代碼,而是定義一個處理程序,這樣當服務器接收到一個傳入的請求時,服務器就可以調用你的函數。
2.5.1 創建SocketServer TCP服務器
在示例2-8中,首先導入服務器類,然后定義與之前相同的主機常量。其次是請求處理程序類,最后啟動它。更多細節請查看下面的代碼片段。
示例2-8 SocketServer時間戳TCP服務器(tsTservSS.py)
通過使用SocketServer類、TCPServer和StreamRequestHandler,該腳本創建了一個時間戳TCP服務器。
逐行解釋
第1~9行
最初的部分包括從SocketServer導入正確的類。注意,這里使用了Python 2.4中引入的多行導入功能。如果使用的是較早版本的Python,那么將不得不使用完全限定的module.attribute名稱,或者在同一行中導入兩個屬性。
from SocketServer import TCPServer as TCP, StreamRequestHandler as SRH
第11~15行
這里進行了大量的工作。我們得到了請求處理程序MyRequestHandler,作為SocketServer中StreamRequestHandler的一個子類,并重寫了它的handle()方法,該方法在基類Request中默認情況下沒有任何行為。
def handle(self):
pass
當接收到一個來自客戶端的消息時,它就會調用handle()方法。而StreamRequestHandler類將輸入和輸出套接字看作類似文件的對象,因此我們將使用readline()來獲取客戶端消息,并利用write()將字符串發送回客戶端。
因此,在客戶端和服務器代碼中,需要額外的回車和換行符。實際上,在代碼中你不會看到它,因為我們只是重用那些來自客戶端的符號。除了這些細微的差別之外,它看起來就像以前的服務器。
第17~19行
最后的代碼利用給定的主機信息和請求處理類創建了TCP服務器。然后,無限循環地等待并服務于客戶端請求。
2.5.2 創建SocketServer TCP客戶端
如示例2-9所示,這里的客戶端很自然地非常像最初的客戶端,比服務器像得多,但必須稍微調整它以使其與新服務器很好地工作。
示例2-9 SocketServer時間戳TCP客戶端(tsTclntSS.py)
這是一個時間戳TCP客戶端,它知道如何與類似文件的SocketServer類StreamRequest Handler對象通信。
逐行解釋
第1~8行
這里沒有什么特別之處,這是復制原來客戶端的代碼。
第10~21行
SocketServer請求處理程序的默認行為是接受連接、獲取請求,然后關閉連接。由于這個原因,我們不能在應用程序整個執行過程中都保持連接,因此每次向服務器發送消息時,都需要創建一個新的套接字。
這種行為使得TCP服務器更像是一個UDP服務器。然而,通過重寫請求處理類中適當的方法就可以改變它。不過,我們將其留作本章末尾的一個練習。
除了客戶端現在有點“由內而外”(因為我們必須每次都創建一個連接)這個事實之外,其他一些小的區別已經在服務器代碼的逐行解釋中給出:因為這里使用的處理程序類對待套接字通信就像文件一樣,所以必須發送行終止符(回車和換行符)。而服務器只是保留并重用這里發送的終止符。當得到從服務器返回的消息時,用strip()函數對其進行處理并使用由print聲明自動提供的換行符。
2.5.3 執行TCP服務器和客戶端
這里是SocketServer TCP客戶端的輸出。
$ tsTclntSS.py
> 'Tis but a scratch.
[Tue Apr 18 20:55:49 2006] 'Tis but a scratch.
> Just a flesh wound.
[Tue Apr 18 20:55:56 2006] Just a flesh wound.
>
$
這是服務器的輸出。
$ tsTservSS.py
waiting for connection...
...connected from: ('127.0.0.1', 53476)
...connected from: ('127.0.0.1', 53477)
此時的輸出與最初的TCP客戶端和服務器的輸出類似。然而,你應該會發現,我們連接了服務器兩次。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的python3 socketserver_《Python核心编程(第3版)》——2.5 *SocketServer模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 皮蛋没有糖心是怎么回事
- 下一篇: 快手上一个穿云箭多少人民币