Tidy up code and remove initial framework

This commit is contained in:
Kayomn 2021-09-30 01:25:55 +01:00
parent a46242999b
commit f6fede5872
2 changed files with 63 additions and 100 deletions

View File

@ -4,23 +4,32 @@ __status__ = "Development"
if (__name__ == "__main__"): if (__name__ == "__main__"):
import config import config
import socket as network import socket
import message import select
import sys
def init() -> None:
address = (config.host, config.port) address = (config.host, config.port)
print("Starting connection to", address) print("Starting connection to", address)
with network.socket(network.AF_INET, network.SOCK_STREAM) as socket: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
socket.setblocking(False) server_socket.setblocking(False)
socket.connect_ex(address) server_socket.connect_ex(address)
inputs = [sys.stdin, server_socket]
while True: while True:
message_body = input("Enter a message: ") readable_io, _, _ = select.select(inputs, [], [])
print("\n") for io in readable_io:
socket.send(message.serialize("Kayomn", message_body)) if (io == server_socket):
print(io.recv(4096))
init() elif (io == sys.stdin):
message = sys.stdin.readline()
server_socket.send(message.encode("utf-8"))
sys.stdout.write("<You>")
sys.stdout.write(message)
sys.stdout.flush()

132
server.py
View File

@ -3,102 +3,56 @@ __version__ = "0.0.1"
__status__ = "Development" __status__ = "Development"
if (__name__ == "__main__"): if (__name__ == "__main__"):
import threading
import config import config
import traceback import socket
import socket as network
import selectors
import message
class User: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
def __init__(self, user_socket: network.socket):
self.socket = user_socket
self.connection, self.address = user_socket.accept()
self.selector = selectors.DefaultSelector()
print("Accepted connection from", self.address)
self.connection.setblocking(False)
def close(self):
self.selector.close()
self.socket.close()
def read(self):
try:
# Should be ready to read
data = self.socket.recv(4096)
except BlockingIOError:
# Resource temporarily unavailable (errno EWOULDBLOCK)
pass
else:
if data:
print(message.deserialize(data))
else:
raise RuntimeError("Peer closed.")
def write(self):
pass
def run(self):
try:
while True:
events = self.selector.select(timeout=None)
for (key, mask) in events:
try:
if (mask & selectors.EVENT_READ):
self.read()
elif (mask & selectors.EVENT_WRITE):
self.write()
except Exception:
print(f"Exception raised on {self.address}: {traceback.format_exc()}"),
self.socket.close()
if not self.selector.get_map():
break
except KeyboardInterrupt:
print("caught keyboard interrupt, exiting")
finally:
self.selector.close()
def init():
address = (config.host, config.port)
selector = selectors.DefaultSelector()
with network.socket(network.AF_INET, network.SOCK_STREAM) as socket:
# Avoid bind() exception: OSError: [Errno 48] Address already in use # Avoid bind() exception: OSError: [Errno 48] Address already in use
socket.setsockopt(network.SOL_SOCKET, network.SO_REUSEADDR, 1) client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
socket.bind(address) client_socket.bind((config.host, config.port))
socket.listen() client_socket.listen()
print("Listening on", address) clients = []
socket.setblocking(False) def spawn_client(client_connection, client_address):
selector.register(socket, selectors.EVENT_READ, data=None) client_connection.send("Welcome to this chatroom!".encode("utf-8"))
users = []
try: try:
data = client_connection.recv(4096)
print("test", data if data else "OOOPS")
while data:
message = "<" + client_address[0] + "> " + data
print(message)
for client in clients:
if client != client_connection:
try:
client.send(message)
except:
client.close()
# if the link is broken, we remove the client
if client_connection in clients:
clients.remove(client_connection)
data = client_connection.recv(4096)
if client_connection in clients:
print("dead")
clients.remove(client_connection)
except:
return
while True: while True:
events = selector.select(timeout=None) connection, address = client_socket.accept()
for (key, mask) in events: clients.append(connection)
if key.data is None:
user = User(key.fileobj)
users.append(user) # prints the address of the user that just connected
user.run() print(address[0] + " connected")
threading.Thread(target=spawn_client, args=(connection, address)).start()
except KeyboardInterrupt:
print("Caught keyboard interrupt, exiting")
finally:
for user in users:
user.close()
selector.close()
init()