From 62d124438ec42aed2cdf6c8d1f39c50147d0b75f Mon Sep 17 00:00:00 2001 From: Luca Randazzo <luca.randazzo@student.reutlingen-university.de> Date: Sat, 14 Dec 2024 20:08:11 +0000 Subject: [PATCH] Add ring update --- ring_update.py | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 ring_update.py diff --git a/ring_update.py b/ring_update.py new file mode 100644 index 0000000..e8a03f8 --- /dev/null +++ b/ring_update.py @@ -0,0 +1,151 @@ +#Ring testebn +#Forming a Ring + +import time +import threading +from uuid import uuid4 +import socket +import uuid +import json +import neighbour + +#Neu +leader = False + +#dict member = {"uuid": {"IP",}} + +#Definition Atribute +global members_UUID +global member_IP +members_UUID = [] #List for members in the ring +member_IP = [] #List for ip Adresses of the members +broadcast_ip = "255.255.255.255" #Broadcast-adress in the Network +port = 12348 #Port that is used for the discovery of new server participants +server_ip = "0.0.0.0" #IP that enables the server to receive all messages that are passed to the port +my_ID = str(uuid.uuid4()) #Creating a unique ip Adress using uuid4 +ringport = 12343 +hostname = socket.gethostname() +ip_address = socket.gethostbyname(hostname) + +#Muss dauerhaft erfolgen +def lausche_update_Ring(): + global member_IP + # Erstellen eines UDP-Sockets + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + # Setze den Socket in den Broadcast-Modus + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + # Sende die Nachricht an die Broadcast-Adresse + sock.bind(("0.0.0.0", ringport)) + while True: + + try: + data, addr = sock.recvfrom(1024) # Antwort empfangen + member_IP = json.loads(data.decode()) + print(f"Ring Update erhalten: {member_IP}") + #send_update_to_ring() + #nachricht_update_ring() + except json.JSONDecodeError: + print("Fehler beim Decodieren der JSON-Daten.") + +#Function of Leader. Server is listeng to the Port to greet new servers and Update Ring Topology +def new_server_in_ring(): + global members_UUID + global member_IP + # Erstellen eines UDP-Sockets + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + # Setze den Socket in den Broadcast-Modus + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + # Binde den Socket an die Adresse und den Port + sock.bind(("0.0.0.0", port)) + print("Server läuft und wartet auf Broadcast-Nachrichten von neuen Servern.") + while True: + #Lauscht ob es ene Nachricht von anderen servern erhält + data, addr = sock.recvfrom(1024) # Puffergröße 1024 Bytes + print(f"Nachricht empfangen von {addr}: {data.decode()}") + msg = 'es gibt bereits server' + new_server_ip, new_server_port = addr + new_ID = data.decode() + new_ID = new_ID.split(": ")[1] + + # ??? notwendig ??? + #Prüfen ob die ID bereis vorhanden ist und Server nur kurz die Verbindung verloren hat. Kann eigemtlich nich eintreten, da ID immer neu generiert wird + if new_ID in members_UUID: + #msg = f"Welcome Back. Aktueller Ring: {json.dumps(members)}".encode() + Nachricht = json.dumps(members_UUID).encode() + else: + members_UUID.append(new_ID) + member_IP.append(new_server_ip) + sock.sendto(msg.encode(), (new_server_ip, new_server_port)) + print(f"Members des Rings sind: {members_UUID}") + print(f"Der neue IP_Ring ist: {member_IP}") + + #Ring Update losschicken + send_update_to_ring() + + +#Server tritt bei und macht sich für andere Server bemerkbar +def server_enters(): + global members_UUID + msg = f"Ich bin neu: {my_ID}".encode() #Greeting message of the server entering the chat + # Erstellen eines UDP-Sockets + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + # Setze den Socket in den Broadcast-Modus + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + # Sende die Nachricht an die Broadcast-Adresse + sock.sendto(msg, (broadcast_ip, port)) + # Warte etwas auf eine Antwort + sock.settimeout(2) + try: + data, addr = sock.recvfrom(1024) # Antwort empfangen + print(f"Antwort von {addr}: {data.decode()}") + lausche_update_Ring() + sock.close() + #Liste der Members wird dem Neuzugang gesendet, Es wird geprüft, ob die json Datei ausgelesen werden kann. Json wird genutzt um Liste Vollständig zu übergeben + #try: + #members_UUID = json.loads(data.decode()) + #print(f"Der neue Ring ist: {members_UUID}") + #print(f"Der neue IP_Ring ist: {member_IP}") + + #nachricht_update_ring() + #except json.JSONDecodeError: + #print("Fehler beim Decodieren der JSON-Daten.") + + #Übergabe der Ring Teilnehmer durch den Server an Alle anderen Teilnehnmer!! + except socket.timeout: + #If no answer is received the server sets itself as leader + print(f"Keine Antwort erhalten. Ich bin jetzt der Leader. Meine ID: {my_ID}") + #Leader fügt sich selbst als Teilnehmer in den Ring ein + members_UUID.append(my_ID) + member_IP.append(ip_address) + sock.close() + new_server_in_ring() + +#Server tritt in den Ring ein/formt den Ring +def send_update_to_ring(): + global member_IP + right_neighbour = neighbour.get_neighbour(member_IP, ip_address, 'right') + if not right_neighbour: + print("No left neighbour to send updates.") + return + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + data = json.dumps(member_IP).encode() + try: + sock.sendto(data, (right_neighbour , ringport)) + except Exception as e: + print(f"Error sending data: {e}") + sock.close() + +'LUCA' #Multiprosessing einfügen + +if __name__ == "__main__": + # Thread 1 und 2 erstellen + thread1 = f"Thread1-{my_ID}" + thread1 = threading.Thread(target=server_enters) + thread2 = threading.Thread(target=lausche_update_Ring) + + # Starten der Threads + thread1.start() + #thread2.start() + +# Schließe den Socket an welchem Punkt?? +#sock.close() -- GitLab