From c314bc601b3abb08d6c844862e11e59809b5b4a7 Mon Sep 17 00:00:00 2001 From: Katharina <katharina.willig@outlook.com> Date: Thu, 14 Nov 2024 22:08:09 +0100 Subject: [PATCH] add server and client with threads --- __pycache__/server.cpython-313.pyc | Bin 0 -> 2585 bytes clients.py | 32 ++++++++++ server.py | 52 +++++++++++++++ tcp_server.py | 98 ----------------------------- udp_clients.py | 38 ----------- 5 files changed, 84 insertions(+), 136 deletions(-) create mode 100644 __pycache__/server.cpython-313.pyc create mode 100644 clients.py create mode 100644 server.py delete mode 100644 tcp_server.py delete mode 100644 udp_clients.py diff --git a/__pycache__/server.cpython-313.pyc b/__pycache__/server.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b687e02c52c496945deeddac12b80431a6bd478f GIT binary patch literal 2585 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 HPO$p`i@@FM literal 0 HcmV?d00001 diff --git a/clients.py b/clients.py new file mode 100644 index 0000000..5796a2c --- /dev/null +++ b/clients.py @@ -0,0 +1,32 @@ +import socket +import threading + +nickname=input("Choose a mickname: ") + +client=socket.socket(socket.AF_INET, socket.SOCK_STREAM) +client.connect(('127.0.0.1', 55555)) + +def receive(): + while True: + try: + message=client.recv(1024).decode() + if message=='NICK': + client.send(nickname.encode()) + else: + print(message) + except: + print("An error occured") + client.close() + break + +def write(): + while True: + message=f'{nickname}: {input("")}'#as soon as user clicks enter and sends new input, we're asking for the next one, so either close client or send new messages + client.send(message.encode()) + +#run receive and write threat +receive_thread=threading.Thread(target=receive) +receive_thread.start() + +write_thread=threading.Thread(target=write) +write_thread.start() \ No newline at end of file diff --git a/server.py b/server.py new file mode 100644 index 0000000..3023e87 --- /dev/null +++ b/server.py @@ -0,0 +1,52 @@ +import socket +import threading + +host='127.0.0.1' +port=55555 + +print(f'Server ist listening on {host} and port {port}') + +server=socket.socket(socket.AF_INET, socket.SOCK_STREAM) +server.bind((host, port)) +server.listen() + +clients=[] +nicknames=[] + +def broadcast(message): + for client in clients: + client.send(message) + +def handle(client): + while True: + try: + message=client.recv(1024) + broadcast(message) + except: + index=clients.index(client) + clients.remove(client) + client.close() + nickname=nicknames[index] + broadcast(f'{nickname} left the chat'.encode()) + nicknames.remove(nickname) + break + +def receive(): + + while True: + client, address=server.accept() #accept clients all the time + print(f"Connected with {str(address)}") + + client.send('NICK'.encode()) #send to client keyword NICK + nickname=client.recv(1024).decode() #receive nickname from client + nicknames.append(nickname) #append nickname to list + clients.append(client) #append client to list + + print(f'Nickname of client ist {nickname}') + broadcast(f'{nickname} joined the chat'.encode()) #broadcast to all clients connected to server + client.send("Connected to the server".encode()) #send to particular client that connection was successfull + + thread=threading.Thread(target=handle, args=(client,)) #start a thread, which handles the connection with this particular client + thread.start() + +receive() \ No newline at end of file diff --git a/tcp_server.py b/tcp_server.py deleted file mode 100644 index bed7615..0000000 --- a/tcp_server.py +++ /dev/null @@ -1,98 +0,0 @@ -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 deleted file mode 100644 index ff8a238..0000000 --- a/udp_clients.py +++ /dev/null @@ -1,38 +0,0 @@ -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