又看了看ftp作业的要求, 发现不让用socketserver...这么好用的竟然不让用
源码执行流程
自己模仿一个(提取代码)
服务器类
import socket import threading import selectors class TCPServer: def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): self.server_address = server_address # IP端口 self.RequestHandlerClass = RequestHandlerClass # 处理handelr self.__is_shut_down = threading.Event() self.__shutdown_request = False self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind(self.server_address) # 绑定IP, 端口 self.socket.listen(5) def serve_forever(self, poll_interval=0.5): self.__is_shut_down.clear() # 清除事件标志 print("serve_forever") try: with selectors.SelectSelector() as selector: # 类似select的监听 selector.register(self, selectors.EVENT_READ) # while not self.__shutdown_request: # 循环去监听 print(111111111) ready = selector.select(poll_interval) if ready: self._handle_request_noblock() except: raise def _handle_request_noblock(self): request, client_address = self.socket.accept() try: self.process_request(request, client_address) except: self.shutdown_request(request) def process_request(self, request, client_address): t = threading.Thread(target=self.process_request_thread, args=(request, client_address)) t.start() def process_request_thread(self, request, client_address): self.finish_request(request, client_address) def finish_request(self, request, client_address): self.RequestHandlerClass(request, client_address, self) def shutdown_request(self, request): request.colse() def fileno(self): return self.socket.fileno()
handle
class Handle: def __init__(self, request, client_address, server): self.request = request # 请求 self.client_address = client_address # self.server = server # 服务器 try: self.handle() # 初始化时就会去执行handle()方法 finally: self.finish() def handle(self): pass def finish(self): pass
ps:
fileno()方法, select实际上是监听的套接字该方法, 因为我们传入的不是套接字, 所以我们实现了该方法, 并且返回套接字的状态