socketserverhtml
此模塊簡化了socket的編寫。python
一、它有一個基類,定義瞭如何創建鏈接。BaseServer提供了服務類接口,BaseServer使用了select建立了多線程。BaseServer下面有四個類:TCPServer、UnixStreamServer、UDPserver、UnixDatagramServer。json
二、它還提供了請求處理類:定義瞭如何處理用戶數據。定義了三個方法setup\handler\finish,的接口,使用時,從新寫對應方法。服務器
三、使用Forktheard和多線程
BaseServer模塊結構:socket
服務處理類方法: |
做用 |
BaseServer |
超類,提供了API,並利用select建立了多線程。不能直接調用它使用。 |
TCPServer |
建立每一個進程的socket,傳輸TCP數據。同時,也是一個基類。 |
UDPServer |
傳輸UDP數據。 |
UnixStreamServer |
Unix下使用 |
UnixDatagramServer | Unix下使用 |
ThreadingTCPServer | socketserver多路複用版。UDPServer\UnixStreamServer\UnixDatagramServer的多路複用版前加Threading |
服務處理類BaseServer的方法 |
做用 |
fileno() |
返回服務器監聽套接字的整數文件描述符。一般用來傳遞給select.select(), 以容許一個進程監視多個服務器。 |
handle_request() |
處理單個請求。處理順序:get_request(), verify_request(), process_request()。函數 若是用戶提供handle()方法拋出異常,將調用服務器的handle_error()方法。測試 若是self.timeout內沒有請求收到, 將調用handle_timeout()並返回handle_request()。 |
serve_forever(poll_interval=0.5) | 處理請求,直到一個明確的shutdown()請求。每poll_interval秒輪詢一次shutdown。忽略self.timeout。若是你須要作週期性的任務,建議放置在其餘線程。 |
shutdown() |
告訴serve_forever()中止。for python2.6。 |
address_family |
地址簇。socket.AF_INET等 |
HandlerRequestClass |
用戶提供的請求處理類,爲每個請求建立一個實例。 |
server_address |
偵聽的服務器地址。 |
socketSocket |
服務器上偵聽傳入的請求socket對象的服務器。 |
下面方法能夠被子類重載,它們對服務器對象的外部用戶沒有影響。 | |
finish_request() | 實際處理RequestHandlerClass發起的請求並調用其handle()方法。 經常使用。 |
get_request() | 接受socket請求,並返回二元組包含要用於與客戶端通訊的新socket對象,以及客戶端的地址。 |
handle_error(request, client_address) | 若是RequestHandlerClass的handle()方法拋出異常時調用。默認操做是打印traceback到標準輸出,並繼續處理其餘請求。 |
handle_timeout() | 超時處理。默認對於forking服務器是收集退出的子進程狀態,threading服務器則什麼都不作 |
process_request(request, client_address) |
調用finish_request()建立RequestHandlerClass的實例。若是須要,此功能能夠建立新的進程或線程來處理請求,ForkingMixIn和ThreadingMixIn類作到這點。經常使用。 |
server_activate() | 經過服務器的構造函數來激活服務器。默認的行爲只是監聽服務器套接字。可重載。 |
server_bind() | 經過服務器的構造函數中調用綁定socket到所需的地址。可重載。 |
verify_request(request, client_address) | 返回一個布爾值,若是該值爲True ,則該請求將被處理,反之請求將被拒絕。此功能能夠重寫來實現對服務器的訪問控制。默認的實現始終返回True。client_address能夠限定客戶端,好比只處理指定ip區間的請求。 經常使用。 |
服務處理類的變量(屬性): |
做用 |
allow_reuse_address |
是否容許地址重用,默認是False,能夠在子類裏更改。 |
request_queue_size |
請求隊列的大小。若是單個請求須要很長的時間來處理,服務器忙時請求被放置到隊列中,最多能夠放request_queue_size個。一旦隊列已滿,來自客戶端的請求將獲得 「Connection denied」錯誤。默認值一般爲5 ,但能夠被子類覆蓋。 |
socket_type |
服務器使用的套接字類型,socket.SOCK_STREAM和socket.SOCK_DGRAM等。 |
timeout |
超時時間。以秒爲單位,或 None表示沒有超時。若是handle_request()在timeout內沒有收到請求,將調用handle_timeout()。 |
請求處理類的方法: |
做用 |
setup() |
處理請求以前的方法,能夠初始化。 |
handle() |
處理請求的方法,處理與Client交互內容。 |
finish() |
handler()處理完成後運行的方法。用於釋放和清理。 |
#服務端: import socketserver class Mysite(socketserver.BaseRequestHandler): # 必須繼承socketserver基類 def handle(self): # 重寫基類裏的handler()方法,在這個方法裏處理接收、發送請求 while True: recv_data = self.request.recv(1024) data = json.loads(recv_data.decode()) # 爲何用json?,由於我喜歡。。這包裝數字、字符、列表等等數據類型通吃 print(data) if data.lower() == "exit": # 檢測到exit退出 print("客戶端退出!") break self.request.send(json.dumps(data.lower()).encode()) # 發送轉換小寫的數據給客戶端,而後進入到下一個循環 my_server = socketserver.TCPserver(("localhost", 9999), Mysite) # 實例化socketserver,並傳送服務器ip、port和子類 my_server.serve_forever() # 客戶端 import socket class Myclient(object): def __init__(obj): # 接收一個socket實例化的對象 self.conn = obj def handle(self,ip,prot): # 定義一個數據交互的方法 self.conn.connect((ip,port)) # 綁定連接,其它把它放在init方法裏是否是會更好? while Ture: # 循環發送、接收數據 cmd = input('輸入轉換的字符,exit退出!') if cmd.strip().lower() == 'exit': # 若是輸入EXIT退出 print('退出!') break self.conn.send(json.dumps(cmd).encode()) # 發送輸入的數據 recv_data = self.conn.recv(1024) # 接收服務器轉換後的數據 data = json.loads(recv_data.decode()) # json解碼 print('轉換的:{}'.format(data)) my_socket = socket.socket() # 實例化socket對象 my_client = Myclient(my_socket) # 實例化自定義類,並傳入實例化的socket對象 my_client.handle("localhost",9999) # 調用數據交互方法 """以上代碼博客裏手打,未經測試。 """
其它參考資料:
https://www.cnblogs.com/MnCu8261/p/5546823.html