From ce1c93478e233d277b4a2cd3a35f1176c2aecede Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 13:57:50 +0200 Subject: [PATCH 01/15] strings --- src/client/client.py | 38 +++++++++++++++++++++++++ src/server/server.py | 67 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/client/client.py create mode 100644 src/server/server.py diff --git a/src/client/client.py b/src/client/client.py new file mode 100644 index 0000000..cd7bc76 --- /dev/null +++ b/src/client/client.py @@ -0,0 +1,38 @@ +import socket +import threading +import sys + +#Wait for incoming data from server +#.decode is used to turn the message in bytes to a string +def receive(socket, signal): + while signal: + try: + data = socket.recv(32) + print(str(data.decode('utf-8'))) + except: + print("You have been disconnected from the server") + signal = False + break + +#Get host and port +host = input("Host: ") +port = int(input("Port: ")) + +#Attempt connection to server +try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((host, port)) +except: + print("Could not make a connection to the server") + input("Press enter to quit") + sys.exit(0) + +#Create new thread to wait for data +receiveThread = threading.Thread(target = receive, args = (sock, True)) +receiveThread.start() + +#Send data to server +#str.encode is used to turn the string message into bytes so it can be sent across the network +while True: + message = input() + sock.sendall(str.encode(message)) diff --git a/src/server/server.py b/src/server/server.py new file mode 100644 index 0000000..bd0e756 --- /dev/null +++ b/src/server/server.py @@ -0,0 +1,67 @@ +import socket +import threading + +#Variables for holding information about connections +connections = [] +total_connections = 0 + +#Client class, new instance created for each connected client +#Each instance has the socket and address that is associated with items +#Along with an assigned ID and a name chosen by the client +class Client(threading.Thread): + def __init__(self, socket, address, id, name, signal): + threading.Thread.__init__(self) + self.socket = socket + self.address = address + self.id = id + self.name = name + self.signal = signal + + def __str__(self): + return str(self.id) + " " + str(self.address) + + #Attempt to get data from client + #If unable to, assume client has disconnected and remove him from server data + #If able to and we get data back, print it in the server and send it back to every + #client aside from the client that has sent it + #.decode is used to convert the byte data into a printable string + def run(self): + while self.signal: + try: + data = self.socket.recv(32) + except: + print("Client " + str(self.address) + " has disconnected") + self.signal = False + connections.remove(self) + break + if data != "": + print("ID " + str(self.id) + ": " + str(data.decode('utf-8'))) + for client in connections: + if client.id != self.id: + client.socket.sendall(data) + +#Wait for new connections +def newConnections(socket): + while True: + sock, address = socket.accept() + global total_connections + connections.append(Client(sock, address, total_connections, "Name", True)) + connections[len(connections) - 1].start() + print("New connection at ID " + str(connections[len(connections) - 1])) + total_connections += 1 + +def main(): + #Get host and port + host = input("Host: ") + port = int(input("Port: ")) + + #Create new server socket + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.bind((host, port)) + sock.listen(5) + + #Create new thread to wait for connections + newConnectionsThread = threading.Thread(target = newConnections, args = (sock,)) + newConnectionsThread.start() + +main() From 74120c1c0ea54704b92581593b87f9beb3ea5bab Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 14:08:45 +0200 Subject: [PATCH 02/15] socket-improvements --- src/client/client.py | 10 ++++++++-- src/server/server.py | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index cd7bc76..556f442 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -7,8 +7,14 @@ def receive(socket, signal): while signal: try: - data = socket.recv(32) - print(str(data.decode('utf-8'))) + data = b'' + while True: + chunk = socket.recv(4096) + data += chunk + if len(chunk) < 4096: + break + if data: + print(str(data.decode('utf-8'))) except: print("You have been disconnected from the server") signal = False diff --git a/src/server/server.py b/src/server/server.py index bd0e756..aeef87a 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -18,7 +18,7 @@ def __init__(self, socket, address, id, name, signal): self.signal = signal def __str__(self): - return str(self.id) + " " + str(self.address) + return str(self.id) + + str(self.address) #Attempt to get data from client #If unable to, assume client has disconnected and remove him from server data @@ -28,13 +28,18 @@ def __str__(self): def run(self): while self.signal: try: - data = self.socket.recv(32) + data = b'' + while True: + chunk = self.socket.recv(4096) + data += chunk + if len(chunk) < 4096: + break except: - print("Client " + str(self.address) + " has disconnected") + print(Client + str(self.address) + " has disconnected") self.signal = False connections.remove(self) break - if data != "": + if data != b"": print("ID " + str(self.id) + ": " + str(data.decode('utf-8'))) for client in connections: if client.id != self.id: From de41cb8080fd6f41c7565120e0aa7100c6903118 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 14:20:08 +0200 Subject: [PATCH 03/15] fixed --- src/client/client.py | 6 +++--- src/server/server.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 556f442..1fcf278 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -4,8 +4,8 @@ #Wait for incoming data from server #.decode is used to turn the message in bytes to a string -def receive(socket, signal): - while signal: +def receive(socket, connected = True): + while connected: try: data = b'' while True: @@ -17,7 +17,7 @@ def receive(socket, signal): print(str(data.decode('utf-8'))) except: print("You have been disconnected from the server") - signal = False + connected = False break #Get host and port diff --git a/src/server/server.py b/src/server/server.py index aeef87a..1e7b748 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -18,7 +18,7 @@ def __init__(self, socket, address, id, name, signal): self.signal = signal def __str__(self): - return str(self.id) + + str(self.address) + return str(self.id) + " " + str(self.address) #Attempt to get data from client #If unable to, assume client has disconnected and remove him from server data @@ -35,7 +35,7 @@ def run(self): if len(chunk) < 4096: break except: - print(Client + str(self.address) + " has disconnected") + print("Client " + str(self.address) + " has disconnected") self.signal = False connections.remove(self) break @@ -66,7 +66,7 @@ def main(): sock.listen(5) #Create new thread to wait for connections - newConnectionsThread = threading.Thread(target = newConnections, args = (sock,)) + newConnectionsThread = threading.Thread(target = newConnections, args = (sock)) newConnectionsThread.start() main() From 94fa7c84e7c9f31984c2a05f50e7515460a74c67 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 14:53:40 +0200 Subject: [PATCH 04/15] Error handling --- src/client/client.py | 8 ++++---- src/server/server.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 1fcf278..1723508 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -15,8 +15,8 @@ def receive(socket, connected = True): break if data: print(str(data.decode('utf-8'))) - except: - print("You have been disconnected from the server") + except (socket.error, ConnectionResetError) as e: + print("You have been disconnected from the server. Error: " + e.strerror) connected = False break @@ -28,8 +28,8 @@ def receive(socket, connected = True): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) -except: - print("Could not make a connection to the server") +except (socket.error, ConnectionRefusedError) as e: + print("Could not make a connection to the server. Error: " + e.strerror) input("Press enter to quit") sys.exit(0) diff --git a/src/server/server.py b/src/server/server.py index 1e7b748..85c94fb 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -34,7 +34,7 @@ def run(self): data += chunk if len(chunk) < 4096: break - except: + except (socket.error, ConnectionResetError) as e: print("Client " + str(self.address) + " has disconnected") self.signal = False connections.remove(self) @@ -66,7 +66,7 @@ def main(): sock.listen(5) #Create new thread to wait for connections - newConnectionsThread = threading.Thread(target = newConnections, args = (sock)) + newConnectionsThread = threading.Thread(target = newConnections, args = (sock,)) newConnectionsThread.start() main() From fd4148bb793749bdf1c365947a5ed48d7b9c409e Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 15:21:14 +0200 Subject: [PATCH 05/15] thread handling --- src/server/server.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/server/server.py b/src/server/server.py index 85c94fb..43682b4 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -4,6 +4,7 @@ #Variables for holding information about connections connections = [] total_connections = 0 +_connections_lock = threading.Lock() #Client class, new instance created for each connected client #Each instance has the socket and address that is associated with items @@ -37,7 +38,8 @@ def run(self): except (socket.error, ConnectionResetError) as e: print("Client " + str(self.address) + " has disconnected") self.signal = False - connections.remove(self) + with _connections_lock: + connections.remove(self) break if data != b"": print("ID " + str(self.id) + ": " + str(data.decode('utf-8'))) @@ -50,10 +52,11 @@ def newConnections(socket): while True: sock, address = socket.accept() global total_connections - connections.append(Client(sock, address, total_connections, "Name", True)) - connections[len(connections) - 1].start() - print("New connection at ID " + str(connections[len(connections) - 1])) - total_connections += 1 + with _connections_lock: + connections.append(Client(sock, address, total_connections, "Name", True)) + connections[len(connections) - 1].start() + print("New connection at ID " + str(connections[len(connections) - 1])) + total_connections += 1 def main(): #Get host and port From bc59652e7ccfbb0bb78e1c708cb0d2ab9b38c42f Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 15:32:48 +0200 Subject: [PATCH 06/15] thread managements and error handling --- src/client/client.py | 15 +++++++++++---- src/server/server.py | 4 ++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 1723508..5ba743d 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -5,7 +5,9 @@ #Wait for incoming data from server #.decode is used to turn the message in bytes to a string def receive(socket, connected = True): - while connected: + while True: + if not connected: + break try: data = b'' while True: @@ -39,6 +41,11 @@ def receive(socket, connected = True): #Send data to server #str.encode is used to turn the string message into bytes so it can be sent across the network -while True: - message = input() - sock.sendall(str.encode(message)) +# Setup clean exit +try: + while True: + message = input() + sock.sendall(str.encode(message)) +finally: + sock.close() + receiveThread.join() diff --git a/src/server/server.py b/src/server/server.py index 43682b4..d3c6c83 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -61,7 +61,11 @@ def newConnections(socket): def main(): #Get host and port host = input("Host: ") + if not host: + host = "localhost" port = int(input("Port: ")) + if not (1024 <= port <= 65535): + raise ValueError("Port must be between 1024 and 65535") #Create new server socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) From 57a65b81b5ea69f51954c238744f9c080b2f254d Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:08:54 +0200 Subject: [PATCH 07/15] fix CR --- src/client/client.py | 4 ++-- src/server/server.py | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 5ba743d..214a4d9 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -4,9 +4,9 @@ #Wait for incoming data from server #.decode is used to turn the message in bytes to a string -def receive(socket, connected = True): +def receive(socket, stop_event): while True: - if not connected: + if stop_event.is_set(): break try: data = b'' diff --git a/src/server/server.py b/src/server/server.py index d3c6c83..7af0117 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -43,9 +43,10 @@ def run(self): break if data != b"": print("ID " + str(self.id) + ": " + str(data.decode('utf-8'))) - for client in connections: - if client.id != self.id: - client.socket.sendall(data) + with _connections_lock: + for client in connections: + if client.id != self.id: + client.socket.sendall(data) #Wait for new connections def newConnections(socket): @@ -75,5 +76,11 @@ def main(): #Create new thread to wait for connections newConnectionsThread = threading.Thread(target = newConnections, args = (sock,)) newConnectionsThread.start() + + try: + while True: + pass + except KeyboardInterrupt: + sock.close() main() From 088068d5e6ea1b1663d90c2559942a0ce3389d2a Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:14:03 +0200 Subject: [PATCH 08/15] fix cr --- src/client/client.py | 4 +++- src/server/server.py | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/client/client.py b/src/client/client.py index 214a4d9..964e062 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -36,7 +36,8 @@ def receive(socket, stop_event): sys.exit(0) #Create new thread to wait for data -receiveThread = threading.Thread(target = receive, args = (sock, True)) +stop_event = threading.Event() +receiveThread = threading.Thread(target = receive, args = (sock, stop_event)) receiveThread.start() #Send data to server @@ -47,5 +48,6 @@ def receive(socket, stop_event): message = input() sock.sendall(str.encode(message)) finally: + stop_event.set() sock.close() receiveThread.join() diff --git a/src/server/server.py b/src/server/server.py index 7af0117..40e93f5 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -81,6 +81,10 @@ def main(): while True: pass except KeyboardInterrupt: + for client in connections[:]: + client.signal = False + client.socket.close() + newConnectionsThread.join() sock.close() main() From d57378489c57a1f4d215d6f506711a9bc5577963 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:21:48 +0200 Subject: [PATCH 09/15] fix cr --- src/client/client.py | 1 - src/server/server.py | 13 ++++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 964e062..f82bd5b 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -19,7 +19,6 @@ def receive(socket, stop_event): print(str(data.decode('utf-8'))) except (socket.error, ConnectionResetError) as e: print("You have been disconnected from the server. Error: " + e.strerror) - connected = False break #Get host and port diff --git a/src/server/server.py b/src/server/server.py index 40e93f5..833c325 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -35,7 +35,7 @@ def run(self): data += chunk if len(chunk) < 4096: break - except (socket.error, ConnectionResetError) as e: + except (socket.error, ConnectionResetError): print("Client " + str(self.address) + " has disconnected") self.signal = False with _connections_lock: @@ -64,7 +64,12 @@ def main(): host = input("Host: ") if not host: host = "localhost" - port = int(input("Port: ")) + + try: + port = int(input("Port: ")) + except ValueError: + print("Port must be a number") + return if not (1024 <= port <= 65535): raise ValueError("Port must be between 1024 and 65535") @@ -87,4 +92,6 @@ def main(): newConnectionsThread.join() sock.close() -main() + +if __name__ == "__main__": + main() From 638c77c40dde5a50c907ee2c156ce05d6779ec04 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:32:38 +0200 Subject: [PATCH 10/15] fix cr --- src/client/client.py | 4 ++-- src/server/server.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index f82bd5b..3244906 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -18,7 +18,7 @@ def receive(socket, stop_event): if data: print(str(data.decode('utf-8'))) except (socket.error, ConnectionResetError) as e: - print("You have been disconnected from the server. Error: " + e.strerror) + print(f"You have been disconnected from the server. Error: {e.strerror}") break #Get host and port @@ -30,7 +30,7 @@ def receive(socket, stop_event): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) except (socket.error, ConnectionRefusedError) as e: - print("Could not make a connection to the server. Error: " + e.strerror) + print(f"Could not make a connection to the server. Error: {e.strerror}") input("Press enter to quit") sys.exit(0) diff --git a/src/server/server.py b/src/server/server.py index 833c325..79cb474 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -75,16 +75,20 @@ def main(): #Create new server socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.bind((host, port)) - sock.listen(5) + try: + sock.bind((host, port)) + sock.listen(5) + except socket.error as e: + print(f"Failed to bind socket: {e.strerror}") + return #Create new thread to wait for connections newConnectionsThread = threading.Thread(target = newConnections, args = (sock,)) newConnectionsThread.start() + stop_event = threading.Event() try: - while True: - pass + stop_event.wait() except KeyboardInterrupt: for client in connections[:]: client.signal = False From b7ddf7035239a71680f42cfe67a860370ec69592 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:45:15 +0200 Subject: [PATCH 11/15] fix cr --- src/client/client.py | 3 ++- src/server/server.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 3244906..9126112 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -8,6 +8,7 @@ def receive(socket, stop_event): while True: if stop_event.is_set(): break + socket.settimeout(1.0) # 1 second timeout try: data = b'' while True: @@ -17,7 +18,7 @@ def receive(socket, stop_event): break if data: print(str(data.decode('utf-8'))) - except (socket.error, ConnectionResetError) as e: + except (socket.error, ConnectionResetError, socket.timeout) as e: print(f"You have been disconnected from the server. Error: {e.strerror}") break diff --git a/src/server/server.py b/src/server/server.py index 79cb474..9e50cef 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -50,7 +50,8 @@ def run(self): #Wait for new connections def newConnections(socket): - while True: + running = True + while running: sock, address = socket.accept() global total_connections with _connections_lock: From 34f5378ab2cc37b89c548becae586d834f0b98f6 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:54:12 +0200 Subject: [PATCH 12/15] fix cr --- src/client/client.py | 8 +++++++- src/server/server.py | 10 +++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 9126112..6396293 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -24,7 +24,13 @@ def receive(socket, stop_event): #Get host and port host = input("Host: ") -port = int(input("Port: ")) +try: + port = int(input("Port: ")) + if not (1024 <= port <= 65535): + raise ValueError("Port must be between 1024 and 65535") +except ValueError as e: + print(f"Invalid port: {str(e)}") + sys.exit(1) #Attempt connection to server try: diff --git a/src/server/server.py b/src/server/server.py index 9e50cef..aedccd1 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -49,9 +49,8 @@ def run(self): client.socket.sendall(data) #Wait for new connections -def newConnections(socket): - running = True - while running: +def newConnections(socket, stop_event): + while not stop_event.is_set(): sock, address = socket.accept() global total_connections with _connections_lock: @@ -83,17 +82,18 @@ def main(): print(f"Failed to bind socket: {e.strerror}") return + stop_event = threading.Event() #Create new thread to wait for connections - newConnectionsThread = threading.Thread(target = newConnections, args = (sock,)) + newConnectionsThread = threading.Thread(target = newConnections, args = (sock, stop_event)) newConnectionsThread.start() - stop_event = threading.Event() try: stop_event.wait() except KeyboardInterrupt: for client in connections[:]: client.signal = False client.socket.close() + stop_event.set() newConnectionsThread.join() sock.close() From e54d1f6716a2d0d896ae56c29d2c19f61c034d39 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:57:34 +0200 Subject: [PATCH 13/15] fix cr --- src/client/client.py | 5 +++-- src/server/server.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 6396293..37fc106 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -19,7 +19,8 @@ def receive(socket, stop_event): if data: print(str(data.decode('utf-8'))) except (socket.error, ConnectionResetError, socket.timeout) as e: - print(f"You have been disconnected from the server. Error: {e.strerror}") + print(f"You have been disconnected from the server. Error: {str(e)}") + stop_event.set() break #Get host and port @@ -37,7 +38,7 @@ def receive(socket, stop_event): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) except (socket.error, ConnectionRefusedError) as e: - print(f"Could not make a connection to the server. Error: {e.strerror}") + print(f"Could not make a connection to the server. Error: {str(e)}") input("Press enter to quit") sys.exit(0) diff --git a/src/server/server.py b/src/server/server.py index aedccd1..668c051 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -52,8 +52,8 @@ def run(self): def newConnections(socket, stop_event): while not stop_event.is_set(): sock, address = socket.accept() - global total_connections with _connections_lock: + global total_connections connections.append(Client(sock, address, total_connections, "Name", True)) connections[len(connections) - 1].start() print("New connection at ID " + str(connections[len(connections) - 1])) From fee2af5555485e119a44b0a26a8d3277f3626f48 Mon Sep 17 00:00:00 2001 From: Pavel Vaks <129676672+PavelLinearB@users.noreply.github.com> Date: Thu, 20 Feb 2025 07:44:42 +0200 Subject: [PATCH 14/15] Update client.py --- src/client/client.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/client/client.py b/src/client/client.py index 37fc106..1a2cfab 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -11,9 +11,15 @@ def receive(socket, stop_event): socket.settimeout(1.0) # 1 second timeout try: data = b'' + total_size = 0 + max_size = 1024 * 1024 # 1MB limit while True: chunk = socket.recv(4096) data += chunk + total_size += len(chunk) + if total_size > max_size: + print("Message too large, discarding") + break if len(chunk) < 4096: break if data: From f204ed5e979e593877c4d110e61af23ec1ad6c63 Mon Sep 17 00:00:00 2001 From: Pavel Vaks <129676672+PavelLinearB@users.noreply.github.com> Date: Thu, 20 Feb 2025 07:49:19 +0200 Subject: [PATCH 15/15] Update server.py --- src/server/server.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/server/server.py b/src/server/server.py index 668c051..3d23e5b 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -30,9 +30,16 @@ def run(self): while self.signal: try: data = b'' + total_size = 0 + max_size = 1024 * 1024 # 1MB limit while True: chunk = self.socket.recv(4096) data += chunk + total_size += len(chunk) + if total_size > max_size: + print(f"Client {self.id} sent too large message, disconnecting") + self.signal = False + break if len(chunk) < 4096: break except (socket.error, ConnectionResetError): @@ -90,13 +97,18 @@ def main(): try: stop_event.wait() except KeyboardInterrupt: + print("\nShutting down server...") for client in connections[:]: client.signal = False client.socket.close() + try: + client.join(timeout=1.0) + except threading.ThreadError: + pass stop_event.set() newConnectionsThread.join() - sock.close() - + sock.close() + print("Server shutdown complete") if __name__ == "__main__": main()