本文內容參考文章地址:python
https://m.aliyun.com/yunqi/articles/93088/sql
SocketServer是標準庫中的一個高級模塊(Python 3.x中重命名爲socketserver),它的目標是簡化不少樣板代碼,它們是建立網絡客戶端和服務器所必需的代碼。這個模塊中有爲你建立的各類各樣的類,如表2-3所示。編程
除了爲你隱藏了實現細節以外,另外一個不一樣之處是,咱們如今使用類來編寫應用程序。由於以面向對象的方式處理事務有助於組織數據,以及邏輯性地將功能放在正確的地方。你還會注意到,應用程序如今是事件驅動的,這意味着只有在系統中的事件發生時,它們纔會工做。瀏覽器
事件包括消息的發送和接收。事實上,你會看到類定義只包括一個用來接收客戶端消息的事件處理程序。全部其餘的功能都來自使用的SocketServer類。此外,GUI編程(見第5章)也是事件驅動的。你會當即注意到它們的類似性,由於最後一行代碼一般是一個服務器的無限循環,它等待並響應客戶端的服務請求。它工做起來幾乎與本章前面的基礎TCP服務器中的無限while循環同樣。服務器
在原始服務器循環中,咱們阻塞等待請求,當接收到請求時就對其提供服務,而後繼續等待。在此處的服務器循環中,並不是在服務器中建立代碼,而是定義一個處理程序,這樣當服務器接收到一個傳入的請求時,服務器就能夠調用你的函數。網絡
首先導入服務器類,而後定義與以前相同的主機常量。其次是請求處理程序類,最後啓動它。更多細節請查看下面的代碼片斷。socket
經過使用SocketServer類、TCPServer和StreamRequestHandler,該腳本建立了一個時間戳TCP服務器。
#!/usr/bin/env python from SocketServer import (TCPServer as TCP, StreamRequestHandler as SRH) from time import ctime HOST='' PORT=21567 ADDR=(HOST, PORT) class MyRequestHandler(SRH): def handle(self): print '...connected from:', self.client_address self.wfile.write('[%s] %s'%(ctime(), self.rfile.readline())) tcpServ=TCP(ADDR, MyRequestHandler) print 'starting arleady!!! waiting for connection... ' tcpServ.serve_forever()
這裏面沒有寫客戶端,所以用瀏覽器訪問 本機的 21567 端口。tcp
解釋:函數
from SocketServer import (TCPServer as TCP, StreamRequestHandler as SRH)
最初的部分包括從SocketServer導入正確的類。注意,這裏使用了Python 2.4中引入的多行導入功能。若是使用的是較早版本的Python,那麼將不得不使用徹底限定的module.attribute名稱,或者在同一行中導入兩個屬性。spa
class MyRequestHandler(SRH): def handle(self): print '...connected from:', self.client_address self.wfile.write('[%s] %s'%(ctime(), self.rfile.readline()))
這裏進行了大量的工做。咱們獲得了請求處理程序MyRequestHandler,做爲SocketServer中StreamRequestHandler的一個子類,並重寫了它的handle()方法,該方法在基類Request中默認狀況下沒有任何行爲。
def handle(self): pass
當接收到一個來自客戶端的消息時,它就會調用handle()方法。而StreamRequestHandler類將輸入和輸出套接字看做相似文件的對象,所以咱們將使用readline()來獲取客戶端消息,並利用write()將字符串發送回客戶端。
所以,在客戶端和服務器代碼中,須要額外的回車和換行符。實際上,在代碼中你不會看到它,由於咱們只是重用那些來自客戶端的符號。除了這些細微的差異以外,它看起來就像之前的服務器。
tcpServ=TCP(ADDR, MyRequestHandler) print 'starting arleady!!! waiting for connection... ' tcpServ.serve_forever()
最後的代碼利用給定的主機信息和請求處理類建立了TCP服務器。而後,無限循環地等待並服務於客戶端請求。
這裏的客戶端很天然地很是像最初的客戶端,比服務器像得多,但必須稍微調整它以使其與新服務器很好地工做。
SocketServer時間戳TCP客戶端(tsTclntSS.py)
這是一個時間戳TCP客戶端,它知道如何與相似文件的SocketServer類StreamRequest Handler對象通訊。
#!/usr/bin/env python from socket import * HOST='localhost' PORT=21567 BUFSIZ=1024 ADDR=(HOST, PORT) while True: tcpCliSock=socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) data=raw_input('> ') if not data: break tcpCliSock.send("%s\r\n"%data) data=tcpCliSock.recv(BUFSIZ) if not data: break print data.strip() tcpCliSock.close()
SocketServer請求處理程序的默認行爲是接受鏈接、獲取請求,而後關閉鏈接。因爲這個緣由,咱們不能在應用程序整個執行過程當中都保持鏈接,所以每次向服務器發送消息時,都須要建立一個新的套接字。