socketserver模塊是基於socket而來的模塊,它是在socket的基礎上進行了一層封裝,而且實現併發等功能。html
看看具體用法:node
import socketserver #一、引入模塊
class MyServer(socketserver.BaseRequestHandler): #二、本身寫一個類,類名本身隨便定義,而後繼承socketserver這個模塊裏面的BaseRequestHandler這個類
def handle(self): #三、寫一個handle方法,必須叫這個名字,不寫運行父類的pass
#self.request #六、self.request 至關於一個conn
self.request.recv(1024) #七、收消息
msg = '親,學會了嗎'
self.request.send(bytes(msg,encoding='utf-8')) #八、發消息
self.request.close() #九、關閉鏈接
# 拿到了咱們對每一個客戶端的管道,那麼咱們本身在這個方法裏面的就寫咱們接收消息發送消息的邏輯就能夠了
pass
if __name__ == '__mian__':
#thread 線程,如今只須要簡單理解線程,彆着急,後面很快就會講到啦,看下面的圖
server = socketserver.ThreadingTCPServer(('127.0.0.1',8090),MyServer)#四、使用socketserver的ThreadingTCPServer這個類,將IP和端口的元祖傳進去,還須要將上面我們本身定義的類傳進去,獲得一個對象,至關於咱們經過它進行了bind、listen
server.serve_forever() #五、使用咱們上面這個類的對象來執行serve_forever()方法,他的做用就是說,個人服務一直開啓着,就像京東同樣,不能關閉網站,對吧,而且serve_forever()幫咱們進行了accept
#注意:
#有socketserver 那麼有socketclient的嗎?
#固然不會有,我要做爲客戶去訪問京東的時候,京東幫我也客戶端了嗎,客戶端是否是在咱們本身的電腦啊,而且socketserver對客戶端沒有過高的要求,只須要本身寫一些socket就好了
簡單的應用python
xxxxxxxxxx
#服務端
import socketserver
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "127.0.0.1", 9999
# 設置allow_reuse_address容許服務器重用地址
socketserver.TCPServer.allow_reuse_address = True
# 建立一個server, 將服務地址綁定到127.0.0.1:9999
#server = socketserver.TCPServer((HOST, PORT),Myserver)
server = socketserver.ThreadingTCPServer((HOST, PORT),Myserver)
# 讓server永遠運行下去,除非強制中止程序
server.serve_forever()
#客服端
import socket
HOST, PORT = "127.0.0.1", 9999
data = "hello"
# 建立一個socket連接,SOCK_STREAM表明使用TCP協議
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT)) # 連接到客戶端
sock.sendall(bytes(data + "\n", "utf-8")) # 向服務端發送數據
received = str(sock.recv(1024), "utf-8")# 從服務端接收數據
print("Sent: {}".format(data))
print("Received: {}".format(received))
從上圖咱們能夠看出SocketServer主要被抽象爲兩個主要的類: BaseServer類,用於處理鏈接相關的網絡操做 BaseRequestHandler類,用於實際處理數據相關的操做,SocketServer還提供了兩個MixIn類:ThreadingMinxIn和ForkingMixinl 用於擴展server,實現多進程和多線程。web
xxxxxxxxxx
#如下從這幾個主要的類開始作總體分析
#BaseServer類:
# server_activate
# serve_forever
# shutdown
# service_actions
# handle_request
# handlerequest_noblock
# handle_timeout
# verify_request
# process_request
# server_close
# finish_request
# shutdown_request
# close_request
# handle_error
#先看看BaseServer的初始化函數,主要是實現建立server對象,並初始化serve地址和處理請求的類:RequestHandlerClass
def __init__(self, server_address, RequestHandlerClass):
"""Constructor. May be extended, do not override."""
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.__is_shut_down = threading.Event()
self.__shutdown_request = False
#serve_forever函數,建立server對象以後咱們會使用server對象開啓無限循環,接受一個參數poll_interval,用於表示select輪詢的時間,而後進入一個死循環,用select方法進行網絡IO的監聽,這裏經過調用selector.register(self, selectors.EVENT_READ)進行了註冊,當ready有返回是,表示有IO鏈接或者數據,這個時候會調用_handle_request_noblock
def serve_forever(self, poll_interval=0.5):
self.__is_shut_down.clear()
try:
with _ServerSelector() as selector:
selector.register(self, selectors.EVENT_READ) #檢測是否註冊
while not self.__shutdown_request:
ready = selector.select(poll_interval) # 監聽
if ready:
self._handle_request_noblock()
self.service_actions()
finally:
self.__shutdown_request = False
self.__is_shut_down.set()
#handlerequest_noblock函數,即開始處理一個請求,而且是非阻塞。該方法經過get_request方法獲取鏈接,具體的實如今其子類。一旦獲得了鏈接,調用verify_request方法驗證請求。驗證經過,即調用process_request處理請求。若是中途出現錯誤,則調用handle_error處理錯誤,以及shutdown_request結束鏈接,而verify_request中默認直接返回True,因此當驗證經過後講調用process_request
def _handle_request_noblock(self):
try:
request, client_address = self.get_request()
except OSError:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
else:
self.shutdown_request(request)
# process_request函數, process_request方法是mixin的入口,MixIn子類經過重寫該方法,進行多線程或多進程的配置 。調用finish_request完成請求的處理,同時調用shutdown_request結束請求.
def process_request(self, request, client_address):
self.finish_request(request, client_address)
self.shutdown_request(request)
#finish_request函數,關於請求的部分到這裏就已經處理完畢,接下來是要對數據的處理,finish_request方法將會處理完畢請求.
#BaseRequestHandler類,用於實際處理數據相關的操做.
#初始化函數,該類會處理每個請求。初始化對象的時候,設置請求request對象。而後調用setup方法,子類會重寫該方法,用於處理socket鏈接。接下來的將是handler和finish方法。全部對請求的處理,均可以重寫handler方法。
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()