From c9fc3792fd7671e8283d1427496b2a12f7366b30 Mon Sep 17 00:00:00 2001
From: katharinawil <katharina.willig@outlook.com>
Date: Sat, 2 Nov 2024 00:08:21 +0100
Subject: [PATCH] add server und clients

---
 tcp_server.py  | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++
 udp_clients.py | 38 ++++++++++++++++++++
 2 files changed, 136 insertions(+)
 create mode 100644 tcp_server.py
 create mode 100644 udp_clients.py

diff --git a/tcp_server.py b/tcp_server.py
new file mode 100644
index 0000000..bed7615
--- /dev/null
+++ b/tcp_server.py
@@ -0,0 +1,98 @@
+import socket
+import threading
+import multiprocessing
+import time
+import random
+
+# Konfigurationsparameter
+PORT = 5001  # TCP Port für Server
+BROADCAST_PORT = 5000  # UDP Port für Broadcast von Clients
+
+# Lock für die Leader-Wahl
+leader_lock = multiprocessing.Lock()
+leader_ip = None  # Globale Variable für die IP-Adresse des aktuellen Leaders
+
+def form_ring(members):
+    """Funktion zur Ringbildung für Server und Leader-Wahl."""
+    global leader_ip
+    leader_lock.acquire()
+    sorted_binary_ring= sorted([socket.inet_aton(member) for member in members])
+    sorted_ip_ring= [socket.inet_ntoa(node) for node in sorted_binary_ring]
+    return sorted_ip_ring
+
+def get_neighbour(ring, current_node_ip, direction='left'):
+    global leader_id
+    current_node_index= ring.index(current_node_ip) if current_node_ip in ring else -1
+    if current_node_index!= -1: 
+        if direction == 'left':
+            if current_node_index+ 1 == len(ring):
+             return ring[0]
+            else:
+             return ring[current_node_index+ 1]
+        else:
+            if current_node_index== 0: 
+             return ring[len(ring) -1]
+            else:
+             return ring[current_node_index-1]
+    else:
+        return None
+    
+
+def handle_client_connection(client_socket, client_address):
+    """Verarbeitung der Nachrichten von Clients."""
+    print(f"Verbindung vom Client {client_address} akzeptiert.")
+    while True:
+        try:
+            message = client_socket.recv(1024).decode()
+            if message:
+                print(f"Nachricht vom Client {client_address}: {message}")
+                client_socket.sendall(f"Empfangen vom Leader: {message}".encode())
+        except ConnectionError:
+            break
+    client_socket.close()
+
+def start_tcp_server(server_ip, server_address, members):
+    """Startet den TCP-Server und verarbeitet Verbindungen."""
+    global leader_ip
+    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    ########zeile nur wegen 0.0.0.0 später entfernen !!!!! für reuse adrr
+    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+    server_socket.bind(server_address)
+    server_socket.listen()
+    print(f"Server {server_ip} hört auf {server_address}")
+
+    if leader_ip is None:
+        form_ring(members)  # Initiale Leader-Wahl
+
+    while True:
+        client_socket, client_address = server_socket.accept()
+        process = threading.Thread(target=handle_client_connection, args=(client_socket, client_address))
+        process.start()
+
+def server_process(server_ip, server_address, members):
+    """Prozess für jeden Server."""
+    start_tcp_server(server_ip, server_address, members)
+
+if __name__ == "__main__":
+    # Beispiel-Server IP-Adressen (zum Testen) mit 0.0.0.0, für Netzwerk mit IP-Adressen!!!!!!!!!!!!!!!!
+    members = ['0.0.0.0', '0.0.0.0', '0.0.0.0']
+    #servers = ['192.168.1.1', '192.168.1.2', '192.168.1.3']  # Hier IP-Adressen der Server eintragen
+    #server_addresses = [(ip, PORT) for ip in servers] !!!!!!!!!!!
+    server_addresses = [('0.0.0.0', PORT) for ip in members]
+    #members = ['192.168.0.1', '130.234.204.2', '130.234.203.2', '130.234.204.1', '182.4.3.111'] 
+    ######ring formation######
+    ring = form_ring(members)
+    print(ring)
+    neighbour= get_neighbour(ring, '0.0.0.0', 'left')
+    print(neighbour)
+
+    # Starte jeden Server als separaten Prozess
+    processes = []
+    for server_ip, server_address in zip(members, server_addresses):
+        process = multiprocessing.Process(target=server_process, args=(server_ip, server_address, members))
+        process.start()
+        processes.append(process)
+
+    for process in processes:
+        process.join()
\ No newline at end of file
diff --git a/udp_clients.py b/udp_clients.py
new file mode 100644
index 0000000..ff8a238
--- /dev/null
+++ b/udp_clients.py
@@ -0,0 +1,38 @@
+import socket
+import time
+import threading
+
+def udp_broadcast_client(message, broadcast_address='255.255.255.255', port=5000):
+    """Sendet eine Broadcast-Nachricht an alle Server."""
+    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+
+    while True:
+        client_socket.sendto(message.encode(), (broadcast_address, port))
+        print(f"Broadcast gesendet: {message}")
+        time.sleep(3)  # Nachrichten alle 3 Sekunden senden
+
+def receive_responses(port=5001):
+    """Empfängt Antworten vom Leader."""
+    response_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    response_socket.bind(("", port))
+    response_socket.listen()
+
+    while True:
+        conn, addr = response_socket.accept()
+        response = conn.recv(1024).decode()
+        print(f"Antwort vom Server erhalten: {response}")
+        conn.close()
+
+if __name__ == "__main__":
+    # Starte den Broadcast-Client und empfange die Server-Antworten in separaten Threads
+    message = "Hallo, ich bin ein Client!"
+    
+    broadcast_thread = threading.Thread(target=udp_broadcast_client, args=(message,))
+    response_thread = threading.Thread(target=receive_responses)
+
+    broadcast_thread.start()
+    response_thread.start()
+
+    broadcast_thread.join()
+    response_thread.join()
\ No newline at end of file
-- 
GitLab