From 9b1822c2b0e8d497d294a1f7e7890b1dba816e6b Mon Sep 17 00:00:00 2001 From: Katharina <katharina.willig@outlook.com> Date: Wed, 8 Jan 2025 10:30:41 +0100 Subject: [PATCH] add server handling to client --- 2024-12-22_Server_V4.py | 20 +++++++++--- 2025-01-01_Client_V4.py | 72 ++++++++++++++++++++++++++++++++++------- nickname.py | 28 ++++++++++++++++ 3 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 nickname.py diff --git a/2024-12-22_Server_V4.py b/2024-12-22_Server_V4.py index bb3a7a0..6a9c9c5 100644 --- a/2024-12-22_Server_V4.py +++ b/2024-12-22_Server_V4.py @@ -22,8 +22,8 @@ broadcast_ip = "255.255.255.255" #Broadcast-adress in the Network enter_port = 12348 #Port that is used for the discovery of new server participants ringport = 12343 election_port = 12345 -client_broadcast_port = 55555 -client_broadcast_port2 = 33333 +client_broadcast_port = 55555 #client sends, server listens +client_broadcast_port2 = 33333 #server sends, client listens acknowledgement_port = 22222 heartbeat_port = 44444 heartbeat_ip = "255.255.255.0" @@ -343,13 +343,26 @@ def listen_client(): last_three_messages.append(decoded_message) # Store the message for Leader heartbeat #print(f"Message stored: {last_three_messages}") message_id = decoded_message.split(":")[0] # Extract the unique message ID (UUID) from the decoded message + if message_id in processed_message_ids: # Check if the message has already been processed continue # Skip if the message was already processed + + # send acknowledgement to client + if message_id not in processed_message_ids: + #print("heres the received message") + answer = f"received".encode() + server_socket.sendto(answer, (broadcast_ip, client_broadcast_port2)) #????? + + #if decoded_message.__contains__("server?"): + # server_socket.sendto(answer, (broadcast_ip, client_broadcast_port2)) + hold_back_queue.append((message_id, decoded_message)) # Add the message to the hold-back queue process_hold_back_queue() # Process messages in the hold-back queue + except socket.error as e: # Handle socket errors print(f"An error occurred while listening: {e}") break + except KeyboardInterrupt: # Handle server shutdown via keyboard interrupt ????? Funktioniert das?? print("\nShutting down server...") break @@ -384,7 +397,6 @@ def callback(new_value): ########################### End - observation value changes leader ########################### - ########################### Heartbeat ################################# def heartbeat(): @@ -437,7 +449,7 @@ if __name__ == "__main__": thread2 = threading.Thread(target=lausche_update_Ring) # Listens for ring updates #thread3 = threading.Thread(target=frage_benutzer) # Prompts the user for action --> Only for testing! thread4 = threading.Thread(target=zuhören_election) # Listens for election messages - last_three_messages = ["hallo", "2", "oma"] + last_three_messages = [] thread5 = threading.Thread(target=heartbeat) # Start all threads thread1.start() diff --git a/2025-01-01_Client_V4.py b/2025-01-01_Client_V4.py index 6ee994a..bbecde2 100644 --- a/2025-01-01_Client_V4.py +++ b/2025-01-01_Client_V4.py @@ -1,18 +1,26 @@ +#wenn zweiter client joint, wird kein verfügbarer server mehr angezeigt, das skript startet dreimal neu (?) +#dauerhafte ausgabe des waiting for response... +#funktion zum beenden des servers ergänzen (aka keyboardinterrupt) +#senden client info beim keyboardinterrupt + + import socket import threading import time import uuid import sys +import os broadcast_ip = '255.255.255.255'#change ip??? #hard coded? -broadcast_port = 55555 -broadcast_port2 = 33333 +broadcast_port = 55555 #client sends +broadcast_port2 = 33333 #client listens #local host information MY_HOST = socket.gethostname() #socket.gethostbyname(socket.gethostname()) #getip MY_IP = socket.gethostbyname(MY_HOST) #print(f"host:{MY_HOST} and ip: {MY_IP}") +is_server_available = False # create client-socket for broadcast client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -29,8 +37,11 @@ def listen_server(): client_socket2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) client_socket2.bind(('', broadcast_port2)) # listen on broadcast #socket is bind to ALL available IP addresses """receives messages from server.""" - + #client_socket2.settimeout(10) # timeout if server sends no acknowledgment + client_socket2.settimeout(10) global message_id + global is_server_available + last_response_time = time.time() #listener_ready.set() #makes sure that listener is ready while True: try: @@ -43,19 +54,34 @@ def listen_server(): #print(f"Received {data.decode()} from {address}") #debug #ignores broadcast messages with own ip #################please enable it after testing!!!!!!!!!!!!!!!!!!!S #############NEED SMT TO IGNORE############### - #does not work? - #print("here id", message_id) if received_uuid==message_id: - #print("ignore own msg") + #print("ignore own msgs") continue else: _, _, client_message = text.partition(":") print(client_message.strip()) + if decoded_message.__contains__("received"): #and received_uuid==message_id: + print("server is active", decoded_message) + is_server_available = True + #continue + else: + raise Exception("No active server detected") + + except socket.timeout: + #check if server is available + if is_server_available and time.time() - last_response_time > 15: # 15 Sekunden ohne Antwort + print("Server is no longer available.") + is_server_available = False + elif not is_server_available: + print("No server available. Waiting for connection...") + else: + print("Waiting for server to respond...") - #if decoded_message.split(":")[0]==already_received: - # continue - #print("this decoded msg", decoded_message) #debug + #except socket.timeout: #start script again if theres no answer from server + # print("No response from server. Restarting...") + # time.sleep(3) + # os.execv(sys.executable, ['python'] + sys.argv) except socket.error as e: print(f"An error occurred while listening: {e}") @@ -66,11 +92,27 @@ def sender(): """Ermöglicht dem Benutzer, Nachrichten zu schreiben und zu senden.""" global message_id message_id = str(uuid.uuid4()) + #ask for available server first + question=f"{message_id}: server?" + client_socket.sendto(question.encode(), (broadcast_ip, broadcast_port)) + print("Connect to available server...") + #data, address = client_socket.recvfrom(4096) + #server_answer = data.decode() + + #if server_answer.__contains__("received"): + # print("Connected to server.") + nickname = input("Enter your nickname: ") - just_nickname= f"{nickname} entered the chat".encode() + just_nickname= f"{message_id}: {nickname} entered the chat".encode() #client_socket.sendto(just_nickname, (broadcast_ip, broadcast_port)) client_socket.sendto(just_nickname, (broadcast_ip, broadcast_port)) #print("is it leader adresse here", leader_address) + + #else: + #print("No server available") + #client_socket.close() + #os._exit(0) + try: while True: @@ -84,7 +126,7 @@ def sender(): client_socket.sendto(full_message, (broadcast_ip, broadcast_port)) #print("message sended to", broadcast_port) - except KeyboardInterrupt: + except KeyboardInterrupt: ######################whelp....................... # Handle when the user presses Ctrl+C print(f"\n{nickname} left the chat.") @@ -107,4 +149,10 @@ if __name__ == "__main__": #listener_ready.wait() sender_thread = threading.Thread(target=sender) - sender_thread.start() \ No newline at end of file + sender_thread.start() + + + #####wenn kein server dann client beenden#### + ####sendungsbestätigung vom server, wenn client keine rückantwort erhält, dann keine server erreichbar#### + ####beim server rückantwort einbauen#### + ####when no answer then skip#### \ No newline at end of file diff --git a/nickname.py b/nickname.py new file mode 100644 index 0000000..3be7405 --- /dev/null +++ b/nickname.py @@ -0,0 +1,28 @@ +####client####: + if decoded_message.__contains__("Choose an uniquely nickname"): + sender() + + #if decoded_message.split(":")[0]==already_received: + # continue + #print("this decoded msg", decoded_message) #debug + +####server#### + + double_nickname = decoded_message.split(": ")[1] # Extract nickname + entered the chat for checking whether a nickname is already taken + #print("!!!!!!!!!!nickname!!!", double_nickname) + + current_nickname = double_nickname.split(" entered the chat")[0] + nicknames_in_chat = [msg.split(": ")[1].split(" entered the chat")[0] for msg in last_three_messages if "entered the chat" in msg] + print(nicknames_in_chat) #uuid: susi + print(current_nickname) #susi + + if current_nickname in nicknames_in_chat: + print("!!!!!!!!!!!!!!", current_nickname) + broadcast(f"The nickname {current_nickname} is already taken. Choose an uniquely nickname") + nicknames_in_chat.pop() + last_three_messages.pop() + continue + + #if client has left + #make nickname available again + ###################only proceed last 3-5 messages? if yes, how to check for nickname???? \ No newline at end of file -- GitLab