socketserver通信模塊實現併發操做,基於select、epoll、socket、多線程,實現的正真多線程多併發python
socketserver通信模塊底層調用的socket模塊,只是它做了處理基於lo多路複用加多線程,能實現併發操做,1服務器
SocketServer內部使用 IO多路複用 以及 「多線程」 和 「多進程」 ,從而實現併發處理多個客戶端請求的Socket服務端。即:每一個客戶端請求鏈接到服務器時,Socket服務端都會在服務器是建立一個「線程」或者「進程」 專門負責處理當前客戶端的全部請求。多線程
通信模塊實現併發操做服務端,2併發
1,import socketserver #導入模塊,3socket
2,必須建立一個類來,繼承兩個類socketserver和BaseRequestHandler,注意必須建立一個類來繼承這兩個模塊內部指定的類4spa
socketserver,建立類模塊指定繼承類名稱5線程
BaseRequestHandler,建立類模塊指定繼承類名稱6code
注意:這個類對象裏自動封裝了3個普通字段分別爲,self.request(客戶端鏈接對象),self.client_address(客戶端IP和端口),self.server(服務端對象)7server
self.request(客戶端鏈接對象)8對象
self.client_address(客戶端IP和端口)9
self.server(服務端對象)10
3,建立的類裏必須建立一個handle()方法,當客戶端鏈接後就會執行這個handle()方法,因此各類發送數據和接收數據都是寫在這個方法裏11
在這個方法裏經過對象普通字段的self.request(客戶端鏈接對象)來作通信操做12
handle()客戶端鏈接後自動執行方法13
4,ocketserver.ThreadingTCPServer(元祖類型IP端口, 建立的類名稱)設置服務端的IP和端口,而且把建立的類傳進去給模塊14
使用方法:定義變量 = ocketserver.ThreadingTCPServer(元祖類型IP端口, 建立的類名稱)15
如:shezhi = socketserver.ThreadingTCPServer(('127.0.0.1', 9999,), bf)16
5,serve_forever() 執行模塊,循環等待客戶端鏈接,能處理併發操做,一旦有客戶端鏈接就會執行建立類裏的handle方法17
使用方法:設置服務端的IP和端口變量.serve_forever() 18
如:shezhi.serve_forever()19
併發操做服務端代碼20
#!/usr/bin/env python # -*- coding:utf8 -*- """建立併發服務端""" import socketserver #導入模塊 """建立類""" class bf(socketserver.BaseRequestHandler): #建立一個類,繼承兩個類socketserver和BaseRequestHandler,注意必須建立一個類來繼承這兩個模塊內部指定的類 """定義方法""" def handle(self): #對象自動封裝了(客戶端鏈接對象),(客戶端IP和端口),(服務端對象) # print self.request(客戶端鏈接對象),self.client_address(客戶端IP和端口),self.server(服務端對象) b = self.request #客戶端鏈接對象 b.sendall(bytes("你好歡迎你",encoding='utf-8')) #根據accept()接收到客戶端鏈接對象信息,向客戶端發送信息 while True: #當客戶端鏈接成功後,進入循環,保持與客戶端的通信 j = b.recv(1024)#接收客戶端發來的信息 j2 = str(j, encoding='utf-8') #將接收到的客戶端信息轉換成字符串 if j2 == "q": #判斷客戶端輸入q,表示再也不與服務端通信,跳出循環,不在保持客戶端的通信 break b.sendall(bytes(j2+"好",encoding='utf-8')) #將接收到客戶端的信息加上一個好字,在發送給客戶端 """設置服務端IP端口,而且把建立類傳入socketserver模塊""" shezhi = socketserver.ThreadingTCPServer(('127.0.0.1', 9999,), bf) #設置服務端的IP和端口,而且把建立的類傳進去 """執行socketserver模塊""" shezhi.serve_forever() #執行模塊,循環等待客戶端鏈接,能處理併發操做,一旦有客戶端鏈接就會執行建立類裏的handle方法
併發操做服務端流程圖21
重點:注意傳輸數據時的粘包問題22
粘包就是一端發了兩次信息或數據,第一次發的有可能計算機緩衝區還沒發出去,第二次的信息就發到了緩衝區,這樣兩次的信息粘在一塊兒發出去了,爲了不粘包問題,在第一次發送後接收一下另一端是否接收到第一次發的信息,若是接收到才發第二次,若是沒接收到就不發用,recv()阻塞,