72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|