From ce1c93478e233d277b4a2cd3a35f1176c2aecede Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 13:57:50 +0200 Subject: [PATCH 01/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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 adc48bd7a29f4f2e7d25e24fbc66ffaa5a9cd911 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:05:19 +0200 Subject: [PATCH 07/17] copilot --- src/client/client.py | 28 ++++++++++++++-------------- src/server/server.py | 42 ++++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 5ba743d..ddbff38 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -2,12 +2,10 @@ 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, connected = True): - while True: - if not connected: - break +# 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: try: data = b'' while True: @@ -18,29 +16,31 @@ def receive(socket, connected = True): 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("You have been disconnected from the server. Error: " + str(e)) connected = False break -#Get host and port +# Get host and port host = input("Host: ") port = int(input("Port: ")) +name = input("Enter your name: ") -#Attempt connection to server +# Attempt connection to server try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) + sock.sendall(str.encode(name)) # Send the name to the server except (socket.error, ConnectionRefusedError) as e: - print("Could not make a connection to the server. Error: " + e.strerror) + print("Could not make a connection to the server. Error: " + str(e)) input("Press enter to quit") sys.exit(0) -#Create new thread to wait for data -receiveThread = threading.Thread(target = receive, args = (sock, True)) +# 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 +# Send data to server +# str.encode is used to turn the string message into bytes so it can be sent across the network # Setup clean exit try: while True: diff --git a/src/server/server.py b/src/server/server.py index d3c6c83..12814bf 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -1,14 +1,14 @@ import socket import threading -#Variables for holding information about connections +# 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 -#Along with an assigned ID and a name chosen by the client +# 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) @@ -19,13 +19,13 @@ 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) + " " + self.name - #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 + # 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: @@ -47,19 +47,21 @@ def run(self): if client.id != self.id: client.socket.sendall(data) -#Wait for new connections +# Wait for new connections def newConnections(socket): + global total_connections while True: sock, address = socket.accept() - global total_connections + name = sock.recv(1024).decode('utf-8') # Receive the name from the client + client = Client(sock, address, total_connections, name, True) 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 + connections.append(client) + client.start() + print("New connection at ID " + str(client)) + total_connections += 1 def main(): - #Get host and port + # Get host and port host = input("Host: ") if not host: host = "localhost" @@ -67,13 +69,13 @@ def main(): if not (1024 <= port <= 65535): raise ValueError("Port must be between 1024 and 65535") - #Create new server socket + # 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,)) + # Create new thread to wait for connections + newConnectionsThread = threading.Thread(target=newConnections, args=(sock,)) newConnectionsThread.start() main() From a894142042182f3f1c9f24ec3aef3e7f64ad3ed5 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:10:30 +0200 Subject: [PATCH 08/17] fix CR --- src/server/server.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/server/server.py b/src/server/server.py index 12814bf..5da2cfa 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): @@ -77,5 +78,11 @@ def main(): # Create new thread to wait for connections newConnectionsThread = threading.Thread(target=newConnections, args=(sock,)) newConnectionsThread.start() - -main() + try: + while True: + pass + except KeyboardInterrupt: + sock.close() + +if __name__ == "__main__": + main() \ No newline at end of file From c464c01e29f5677d665546114d93d2019d050347 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:17:55 +0200 Subject: [PATCH 09/17] fix cr --- src/client/client.py | 6 ++++++ src/server/server.py | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/client/client.py b/src/client/client.py index ddbff38..f2cb0c8 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -45,7 +45,13 @@ def receive(socket, connected=True): try: while True: message = input() + if not message: # Allow clean exit on empty input + break sock.sendall(str.encode(message)) +except (socket.error, ConnectionResetError) as e: + print(f"Connection error: {e}") finally: + print("Closing connection...") + connected = False # Signal receive thread to stop sock.close() receiveThread.join() diff --git a/src/server/server.py b/src/server/server.py index 5da2cfa..8c9b2fd 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -82,6 +82,16 @@ def main(): while True: pass except KeyboardInterrupt: + print("\nShutting down server...") + # Signal all clients to stop + with _connections_lock: + for client in connections: + client.signal = False + client.socket.close() + # Wait for all client threads to finish + with _connections_lock: + for client in connections: + client.join() sock.close() if __name__ == "__main__": From 39928e06d4db1b371352b23a46ce9507452932e3 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:28:54 +0200 Subject: [PATCH 10/17] fix cr --- src/client/client.py | 9 +++++---- src/server/server.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index f2cb0c8..a58395d 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, connected=True): - while connected: +def receive(socket, stop_event): + while not stop_event.is_set(): try: data = b'' while True: @@ -36,7 +36,8 @@ def receive(socket, connected=True): 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 @@ -52,6 +53,6 @@ def receive(socket, connected=True): print(f"Connection error: {e}") finally: print("Closing connection...") - connected = False # Signal receive thread to stop + stop_event.set() # Signal receive thread to stop sock.close() receiveThread.join() diff --git a/src/server/server.py b/src/server/server.py index 8c9b2fd..0f0954f 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -57,9 +57,9 @@ def newConnections(socket): client = Client(sock, address, total_connections, name, True) with _connections_lock: connections.append(client) + total_connections += 1 client.start() print("New connection at ID " + str(client)) - total_connections += 1 def main(): # Get host and port From 228f382cd5427521bc923a70d8a985687d8062f1 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:34:09 +0200 Subject: [PATCH 11/17] fix cr --- src/client/client.py | 1 - src/server/server.py | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index a58395d..bd4eec4 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -17,7 +17,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: " + str(e)) - connected = False break # Get host and port diff --git a/src/server/server.py b/src/server/server.py index 0f0954f..0ceaff9 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -88,9 +88,6 @@ def main(): for client in connections: client.signal = False client.socket.close() - # Wait for all client threads to finish - with _connections_lock: - for client in connections: client.join() sock.close() From f007076c63a265afd70bef870a7a23a5beef0cac Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:50:46 +0200 Subject: [PATCH 12/17] fix cr --- src/client/client.py | 2 +- src/server/server.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index bd4eec4..3c315dd 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -13,7 +13,7 @@ def receive(socket, stop_event): data += chunk if len(chunk) < 4096: break - if data: + if data and len(data) > 0: print(str(data.decode('utf-8'))) except (socket.error, ConnectionResetError) as e: print("You have been disconnected from the server. Error: " + str(e)) diff --git a/src/server/server.py b/src/server/server.py index 0ceaff9..e3f7174 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -1,4 +1,5 @@ import socket +import sys import threading # Variables for holding information about connections @@ -66,9 +67,13 @@ def main(): 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") + 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: {e}") + sys.exit(1) # Create new server socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -79,8 +84,8 @@ def main(): newConnectionsThread = threading.Thread(target=newConnections, args=(sock,)) newConnectionsThread.start() try: - while True: - pass + stop_event = threading.Event() + stop_event.wait() # Wait indefinitely until KeyboardInterrupt except KeyboardInterrupt: print("\nShutting down server...") # Signal all clients to stop From 80b92c148d072708b6da15e858666933bafa3e61 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 16:55:50 +0200 Subject: [PATCH 13/17] fix cr --- src/client/client.py | 6 +++--- src/server/server.py | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 3c315dd..8257abd 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -26,9 +26,9 @@ def receive(socket, stop_event): # Attempt connection to server try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((host, port)) - sock.sendall(str.encode(name)) # Send the name to the server + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect((host, port)) + sock.sendall(str.encode(name)) except (socket.error, ConnectionRefusedError) as e: print("Could not make a connection to the server. Error: " + str(e)) input("Press enter to quit") diff --git a/src/server/server.py b/src/server/server.py index e3f7174..eefe89d 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -53,14 +53,18 @@ def run(self): def newConnections(socket): global total_connections while True: - sock, address = socket.accept() - name = sock.recv(1024).decode('utf-8') # Receive the name from the client - client = Client(sock, address, total_connections, name, True) - with _connections_lock: - connections.append(client) - total_connections += 1 - client.start() - print("New connection at ID " + str(client)) + try: + sock, address = socket.accept() + name = sock.recv(1024).decode('utf-8') # Receive the name from the client + client = Client(sock, address, total_connections, name, True) + with _connections_lock: + connections.append(client) + total_connections += 1 + client.start() + print("New connection at ID " + str(client)) + except (socket.error, ConnectionError) as e: + print(f"Error accepting connection: {e}") + continue def main(): # Get host and port From 7a3c46ed05fc8d7c8529811278663238ac7d7e3c Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 17:10:08 +0200 Subject: [PATCH 14/17] fix cr --- src/server/server.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/server/server.py b/src/server/server.py index eefe89d..b7a9365 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -81,8 +81,12 @@ 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}") + sys.exit(1) # Create new thread to wait for connections newConnectionsThread = threading.Thread(target=newConnections, args=(sock,)) From 9e8213a728a02397c3a70ea9719c91ffdcaa9eba Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 17:14:47 +0200 Subject: [PATCH 15/17] fix cr --- src/server/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/server.py b/src/server/server.py index b7a9365..349d53d 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -84,6 +84,7 @@ def main(): try: sock.bind((host, port)) sock.listen(5) + sock.settimeout(60) # 60 second timeout except socket.error as e: print(f"Failed to bind socket: {e}") sys.exit(1) From f787209763e2750fb0cc87289c6b486e6b0394bf Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 17:38:51 +0200 Subject: [PATCH 16/17] fix cr --- src/client/client.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/client/client.py b/src/client/client.py index 8257abd..ff8fc4c 100644 --- a/src/client/client.py +++ b/src/client/client.py @@ -29,16 +29,29 @@ def receive(socket, stop_event): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) sock.sendall(str.encode(name)) +except (socket.error, ConnectionRefusedError) as e: + # Create new thread to wait for data + stop_event = threading.Event() + receiveThread = threading.Thread(target=receive, args=(sock, stop_event)) + receiveThread.start() + # Send data to server + try: + while True: + message = input() + if not message: # Allow clean exit on empty input + break + sock.sendall(str.encode(message)) + except (socket.error, ConnectionResetError) as e: + print(f"Connection error: {e}") + finally: + print("Closing connection...") + stop_event.set() # Signal receive thread to stop + receiveThread.join() except (socket.error, ConnectionRefusedError) as e: print("Could not make a connection to the server. Error: " + str(e)) input("Press enter to quit") sys.exit(0) -# Create new thread to wait for data -stop_event = threading.Event() -receiveThread = threading.Thread(target=receive, args=(sock, stop_event)) -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 # Setup clean exit From d7d0bf781b0ce614cc2b41f0c41421a332cbe327 Mon Sep 17 00:00:00 2001 From: PavelLinearB Date: Wed, 19 Feb 2025 17:44:04 +0200 Subject: [PATCH 17/17] Revert "fix cr" This reverts commit 9e8213a728a02397c3a70ea9719c91ffdcaa9eba. --- src/server/server.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server/server.py b/src/server/server.py index 349d53d..b7a9365 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -84,7 +84,6 @@ def main(): try: sock.bind((host, port)) sock.listen(5) - sock.settimeout(60) # 60 second timeout except socket.error as e: print(f"Failed to bind socket: {e}") sys.exit(1)