From 104fe51c6d0e8acb36d76813a1ba8aac3b69ebe1 Mon Sep 17 00:00:00 2001 From: Kyle Johnsen Date: Sat, 18 Dec 2021 09:39:53 -0500 Subject: [PATCH] first commit --- server.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ test_client.py | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 server.py create mode 100644 test_client.py diff --git a/server.py b/server.py new file mode 100644 index 0000000..6e8197f --- /dev/null +++ b/server.py @@ -0,0 +1,64 @@ + +import socket +import selectors +import types +sel = selectors.DefaultSelector() +host = '127.0.0.1' +port = 80 +lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +lsock.bind((host, port)) +lsock.listen() +print('listening on', (host, port)) +lsock.setblocking(False) +sel.register(lsock, selectors.EVENT_READ, data=None) + +clients = [] + +def accept_wrapper(sock): + conn, addr = sock.accept() # Should be ready to read + print('accepted connection from', addr) + conn.setblocking(False) + client = types.SimpleNamespace(addr=addr, inb='', outb='') + events = selectors.EVENT_READ | selectors.EVENT_WRITE + sel.register(conn, events, data=client) + clients.append(client) + +def service_connection(key, mask): + sock = key.fileobj + data = key.data + + if mask & selectors.EVENT_READ: + recv_data = sock.recv(1024) # Should be ready to read + if recv_data: + m = recv_data.decode("utf-8") + messages = m.split("\n") + if len(messages) > 1: + messages[0]= data.inb + messages[0] + data.inb = "" + for message in messages[:-1]: + #send to other clients + for client in clients: + if client.addr != data.addr: + client.outb += message + "\n" + data.inb += messages[-1] + + else: + print('closing connection to', data.addr) + sel.unregister(sock) + sock.close() + if mask & selectors.EVENT_WRITE: + if data.outb: + print('echoing', data.outb, 'to', data.addr) + sent = sock.send(data.outb.encode('utf-8')) # Should be ready to write + data.outb = data.outb[sent:] + +while True: + events = sel.select(timeout=None) + for key, mask in events: + if key.data is None: + accept_wrapper(key.fileobj) + else: + service_connection(key, mask) + + + \ No newline at end of file diff --git a/test_client.py b/test_client.py new file mode 100644 index 0000000..1d34c28 --- /dev/null +++ b/test_client.py @@ -0,0 +1,50 @@ +import selectors +import socket +import types +import time +HOST = '127.0.0.1' # The server's hostname or IP address +PORT = 80 # The port used by the server +sel = selectors.DefaultSelector() +i = 0 +message = "" +def service_connection(key, mask, message): + sock = key.fileobj + data = key.data + if mask & selectors.EVENT_READ: + recv_data = sock.recv(1024) # Should be ready to read + if recv_data: + print('received', repr(recv_data),flush=True) + + if mask & selectors.EVENT_WRITE: + if message: + data.outb += message + message = "" + print('sending', repr(data.outb)) + sent = sock.send(data.outb.encode('utf-8')) # Should be ready to write + data.outb = data.outb[sent:] + +def start_connection(host, port): + server_addr = (host, port) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setblocking(False) + sock.connect_ex(server_addr) + events = selectors.EVENT_READ | selectors.EVENT_WRITE + data = types.SimpleNamespace(outb='') + sel.register(sock, events, data=data) + + +start_connection(HOST, PORT) +while True: + events = sel.select(timeout=None) + for key, mask in events: + if key.data is None: + pass + else: + service_connection(key, mask, message) + message = "" + + i += 1 + if i % 10 == 0: + message = f"hello {i}\n" + + \ No newline at end of file