diff --git a/__pycache__/server.cpython-313.pyc b/__pycache__/server.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b687e02c52c496945deeddac12b80431a6bd478f Binary files /dev/null and b/__pycache__/server.cpython-313.pyc differ diff --git a/clients.py b/clients.py new file mode 100644 index 0000000000000000000000000000000000000000..5796a2cd0fc7df9cccd3d3d1135d577c93d49c1b --- /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 0000000000000000000000000000000000000000..3023e87c2dfe8449058fbfb1ec49e00440572fc0 --- /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 bed7615135fa9f6ba4b8453747bacf1ef9a5057c..0000000000000000000000000000000000000000 --- 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 ff8a238a6503d47c89b5c31269645ac5cd20d2c3..0000000000000000000000000000000000000000 --- 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