import selectors import socket import ServerThread class SMTPServer: def __init__(self, host: str, port: int): self.__host = host self.__port = port self.__socket = None self.__selector = selectors.DefaultSelector() self.__server_threads = [] self.active = False def start_server(self) -> bool: server_address = (self.__host, self.__port) try: self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.__socket.bind(server_address) self.__socket.listen() self.__socket.setblocking(False) self.__selector.register(self.__socket, selectors.EVENT_READ, data=None) self.active = True print(f"Server Listening on {self.__host}:{self.__port}") result = True except OSError as ex: self.__socket.close() self.__socket = None print(f"Error opening the listener: {repr(ex)}") result = False return result def accept_wrapper(self, socket_in: socket): connection, address = socket_in.accept() print("Received Connection from", address) connection.setblocking(False) new_server_thread = ServerThread.ServerThread(connection, address) self.__server_threads.append(new_server_thread) new_server_thread.start() def open_server(self): try: while self.active: events = self.__selector.select(timeout=None) for key, mask in events: if key.data is None: self.accept_wrapper(key.fileobj) else: pass except KeyboardInterrupt as ex: print("Keyboard Exception") for child_thread in self.__server_threads: child_thread.active = False self.active = False finally: self.__selector.close()