Python 多線程套接字socketserver網絡編程

爲何使用socketserver

雖然Python內置的socket和threading模塊能實現簡單的多線程服務器,在非正式環境,隨便用用仍是能夠的,可是若是要在生產環境中使用,那是萬萬不夠的。服務器

Python考慮得很周到,爲了知足咱們對多線程網絡服務器的需求,提供了"socketserver"模塊。socketserver在內部使用IO多路複用以及多線程/進程機制,實現了併發處理多個客戶端請求的socket服務端。每一個客戶端請求鏈接到服務器時,socketserver服務端都會建立一個「線程」或者「進程」 專門負責處理當前客戶端的全部請求。網絡

使用socketserver要點

  • 建立一個server類,繼承"socketserver.BaseRequestHandler";
  • 這個類中必須重寫一個名字爲"handle"的方法,不能是別的名字,在此進行業務邏輯處理(好比收發數據等);
  • 將這個新建的類,連同服務器的IP和端口做爲參數傳遞給"ThreadingTCPServer()"實例化;
  • 啓動"ThreadingTCPServerObj.serve_forever()"。

栗子

服務端

import socketserver # 1.必須繼承socketserver.BaseRequestHandler類,後臺自動創建雙工通訊,等待客戶端鏈接
class MySockServer(socketserver.BaseRequestHandler): def handle(self):
     # 2.進行收發數據
# request對象進行接收和發送數據 request = self.request request.send('歡迎訪問socketserver服務器'.encode())  # 發送數據send() while True: data = request.recv(1024).decode()          # 接收數據recv() if data == 'exit': print('斷開與%s的鏈接!' % (self.client_address,)) break elif data: print('來自%s客戶端向你發來數據:%s' % (self.client_address, data)) request.send('服務器已收到數據'.encode())   # 發送數據 if __name__ == '__main__': # 3.建立一個多線程TCP服務器對象,綁定IP和端口 tcp_server = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MySockServer) print('啓動服務器!') # 4.啓動服務器,服務器將一直保持運行狀態 tcp_server.serve_forever()

 

分析一下服務器端的代碼,核心要點有這些:多線程

  • 鏈接數據封裝在"self.request"屬性中!經過"self.request"對象調用"send()"和"recv()"方法。
  • "handle()"方法是整個通訊的處理核心(業務邏輯處理,如收發數據等),一旦它運行結束,當前鏈接也就斷開了(但其餘的線程和客戶端還正常),所以通常在此設置一個無限循環。
  • 注意"sock_server = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MySockServer)"中參數傳遞的方法。
  • "sock_server.serve_forever()"表示該服務器在正常狀況下將永遠運行。

客戶端

import socket # 客戶端依然使用socket模塊就能夠了,不須要導入socketserver模塊
 IP_PORT = ('127.0.0.1', 8888) # 1.建立socket對象
sock
= socket.socket()
# 2.與服務端鏈接,創建雙工通訊 sock.connect(IP_PORT) sock.settimeout(
0.5)
# 3.進行收發數據 data
= sock.recv(1024).decode()    # 接收數據recv() print('接收返回數據:%s' % data) while True: inp = input('輸入要發送的數據:').strip() if not inp: continue sock.send(inp.encode())    # 發送數據send() if inp == 'exit': print('謝謝使用,再見!') break data = sock.recv(1024).decode() print('接收返回數據:%s' % data)
# 4.斷開鏈接 sock.close()

客戶端的代碼很好理解,依然使用socket模塊就能夠了,不須要導入socketserver模塊。併發

 

  至此,轉載請註明出處。socket

相關文章
相關標籤/搜索