python3-socketserver
- 2020 年 1 月 9 日
- 筆記
socketserver模組
模組socketserver是標準庫提供的伺服器框架基礎.
這個框架包括了BaseHTTPServer , SimpleHTTPServer , CGIHTTPServer , SimpleXMLRPCServer , DocXMLRPCServer
等伺服器,他們在基本伺服器的基礎上添加了各種功能。
socketserver包含了4個基本的伺服器:
1.TCPServer(支援TCP套接字流)
2.UDPServer(支援UDP數據報套接字)
3.UnixStreamServer和UnixDatagramServer
編寫服務端底層流程:
伺服器接受客戶端連接請求——》實例話一個請求處理程式——》根據伺服器類和請求處理程式類,調用處理方法。
例如:
基本請求程式類(BaseRequestHandler)調用方法 handle 。此方法通過屬性 self.request 來訪問客戶端套接字、
StreamRequestHandler類(處理流),通過屬性self.rfile(用於讀取)和self.wfile(用於寫入),進行與客戶端通訊
基於tcp的socketserver,自定義類中:
conn,client_addr=socket(AF_INET,SOCK_STREAM)
- self.server即套接字對象 <socketserver.ThreadingTCPServer object at 0x000001DA1221FB00>
- self.request即一個鏈接 self.request = conn ; 如: <socket.socket fd=472, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 59405)>
- self.client_address即客戶端地址 self.client_address = client_addr ; ('127.0.0.1', 59405)
基於udp的socketserver,自定義類中:
- self.request是一個元組(第一個元素是客戶端發來的數據,第二部分是服務端的udp套接字對象) 如:(b'adsf', <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8080)>)
- self.client_address即客戶端地址 ('127.0.0.1', 50323)
基於TCP鏈接的簡單並發程式
服務端:
import socketserver # 自定義類來實現通訊循環 class MyTCPHandler(socketserver.BaseRequestHandler): # 必須寫入handle方法,建立鏈接時會自動執行handle方法 def handle(self): while True: try: data = self.request.recv(1024) if not data: break print('->client:', data) self.request.send(data.upper()) except ConnectionResetError: break self.request.close() if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyTCPHandler) server.serve_forever() # 鏈接循環
客戶端1/2/3/4……
import socket client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: client.send('hello'.encode('utf-8')) data = client.recv(1024) print(data)
基於UDP無鏈接的簡單並發程式
服務端:
import socketserver # 自定義類來實現通訊循環 class MyUDPHander(socketserver.BaseRequestHandler): def handle(self): data,sock = self.request sock.sendto(data.upper(),self.client_address) if __name__ == '__main__': server = socketserver.ThreadingUDPServer(('127.0.0.1', 8080), MyUDPHander) server.serve_forever() # 鏈接循環
客戶端1/2/3/4……:
from socket import * client = socket(AF_INET,SOCK_DGRAM) while True: client.sendto(b'hello',('127.0.0.1',8080)) data,server_add = client.recvfrom(1024) print(data)
錯誤筆記:
ConnectionAbortedError: [WinError 10053] 你的主機中的軟體中止了一個已建立的連接。
– 服務端程式碼錯誤
– 解決方法:自定義handler類內必須寫入handle方法
ConnectionRefusedError: [WinError 10061] 由於目標電腦積極拒絕,無法連接。
– 解決方法:kill相關進程重新啟動