diff --git a/chat_server.py b/chat_server.py new file mode 100644 index 0000000000000000000000000000000000000000..aecfed24ca3b834758d9bb8db092a3cdf646dfef --- /dev/null +++ b/chat_server.py @@ -0,0 +1,5 @@ +import socket + +host = socket.gethostname() +server_address =socket.gethostbyname(host) +print(server_address) \ No newline at end of file diff --git a/client.py b/client.py index 6bf73edd3e27d1cc58bcf6d037ccf854e12312d4..2e322913ad354c9af6aa714a700c50ba22c23d96 100644 --- a/client.py +++ b/client.py @@ -2,10 +2,18 @@ import multiprocessing import socket import threading import re +import struct + +client_broadcast_listener_port = 49153 + +client_receive_message_multicast_port = 51001 +multicast_group_ip = '224.0.1.1' class Client(multiprocessing.Process): registered_server = None + host = socket.gethostname() + client_address = socket.gethostbyname(host) def __init__(self): self.run() @@ -15,31 +23,31 @@ class Client(multiprocessing.Process): action = input("Enter type of action ('r' to register): ") if (action == "r"): group = input("Which group dou you want to join? ") - self.register(5970, "register", group) + self.register("register", group) send_thread = threading.Thread(target=self.send_message) - #receive_thread = threading.Thread(target=receive_messages) + receive_thread = threading.Thread(target=self.receive_messages) send_thread.start() - #receive_thread.start() + receive_thread.start() # waiting for thread to stop = prevent the programm from shutdown before thread is stopped send_thread.join() - #receive_thread.join() + receive_thread.join() else: message = input("Enter message:") print(message) - def register(self, port, message_type, message_group): + def register(self, message_type, message_group): - PORT = port MSG = bytes(message_type + '_' + message_group, 'utf-8') broadcast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) broadcast_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - broadcast_socket.sendto(MSG, ('<broadcast>', PORT)) + broadcast_socket.sendto(MSG, ('<broadcast>', client_broadcast_listener_port)) + data, server = broadcast_socket.recvfrom(1024) print('Received message from server: ', data.decode('utf-8')) @@ -73,7 +81,33 @@ class Client(multiprocessing.Process): client_socket.close() - #client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - #client_socket.connect((self.server_address, self.server_port)) - #client_socket.sendto(str.encode(message), self.registered_server) - #client_socket.close() + def receive_messages(self): + print("Listening for groupchat multicast messages") + + client_receive_message_multicast_port + + #multicast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + #multicast_socket.bind(('0.0.0.0', client_receive_message_multicast_port)) + + # Füge die Multicast-Gruppe dem lokalen Interface hinzu + #group = socket.inet_aton(self.client_address) + # mreq = struct.pack('4sL', group, socket.INADDR_ANY) + #multicast_socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + + multicast_get_message_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + multicast_get_message_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + multicast_get_message_socket.bind(('', client_receive_message_multicast_port)) + mreq = struct.pack('4sl', socket.inet_aton(multicast_group_ip), socket.INADDR_ANY) + print(mreq) + + multicast_get_message_socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + + # Empfange die Nachricht + while True: + print('I am there') + data, addr = multicast_get_message_socket.recv(1024) + print(data) + print(f"Empfangene Nachricht von {addr}: {data.decode()}") + + diff --git a/client_register.py b/client_register.py index 6a74f8f21d9768675717b6ab1e3daa2f5ccb53ae..bce0baf5e10adf196943e7f6b8815205e42a3fbb 100644 --- a/client_register.py +++ b/client_register.py @@ -4,4 +4,4 @@ import time if __name__ == '__main__': client = Client() - time.sleep(10) + time.sleep(20) diff --git a/main.py b/main_server.py similarity index 94% rename from main.py rename to main_server.py index de9736ce0f4b1e218317e2ed12cb6696e3b7a9cb..379de3f62dda8f15e9a6568c2f97be1712cec2d6 100644 --- a/main.py +++ b/main_server.py @@ -10,6 +10,6 @@ if __name__ == '__main__': server_cache = dict() clients_cache = dict() server = Server(client_address, server_id, server_port, server_cache, clients_cache) - time.sleep(10) + time.sleep(20) diff --git a/server.py b/server.py index 81f7ec0dc92ecbcceaee34ccb88debbe2463e6b1..e555e38a0a3e9ffce40080239743717d3f9e7648 100644 --- a/server.py +++ b/server.py @@ -3,8 +3,21 @@ import socket import threading import json +client_broadcast_listener_port = 49153 +server_broadcast_listener_port = 49154 + +client_receive_chat_tcp_port = 50001 +client_forward_message_multicast_port = 51000 + +multicast_group_ip = '224.0.1.1' + + + + class Server(multiprocessing.Process): - server_address = '127.0.0.1' + #server_address = '127.0.0.1' + host = socket.gethostname() + server_address = socket.gethostbyname(host) client_cache_key_offset = 0 local_servers_cache = dict() local_clients_cache = dict() @@ -56,7 +69,7 @@ class Server(multiprocessing.Process): listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Bind socket to address and port - listen_socket.bind((MY_IP, BROADCAST_PORT)) + listen_socket.bind((self.server_address, client_broadcast_listener_port)) print(self.server_id+": "+"Listening to client register broadcast messages") @@ -112,6 +125,13 @@ class Server(multiprocessing.Process): client_count = client_count + 1 return client_count + + def find_group_of_client(self, addr): + for key in self.local_clients_cache: + value = self.local_clients_cache[key][0] + if value == addr[0]: + group = key[0] + return group # Create and run new server def create_server(self, server_id, client_address): @@ -178,14 +198,48 @@ class Server(multiprocessing.Process): print(self.server_id+": "+"Group-chat server is listening for client messages at port: ", self.server_port) while True: - conn, addr = server_socket.accept() + connection, addr = server_socket.accept() + print(addr) print(f"Connection established with {addr}") - data = conn.recv(1024) - print(f"Received message from client: {data.decode('utf-8')}") + message = connection.recv(1024) + print(f"Received message from client: {message.decode('utf-8')}") response = "Hello, client! I received your message." - conn.sendall(bytes(response, 'utf-8')) + connection.sendall(bytes(response, 'utf-8')) + connection.close() - conn.close() - + if message: + self.distribute_chat_message(message, addr) + #print(addr[0]) + + def distribute_chat_message(self, message, addr): + group = self.find_group_of_client(addr) + + receiver_list = [] + + for key in self.local_clients_cache: + if group in key: + receiver_list.append(self.local_clients_cache[key][0]) + print("Receiver list", receiver_list) + + distribute_chat_thread = threading.Thread(target=self.multicast_chat_message(message, receiver_list)) + distribute_chat_thread.start() + + + #print(group) + #print(message.decode('utf-8')) + + def multicast_chat_message(self, message, receiver_list): + for client in receiver_list: + multicast_address = (client, client_forward_message_multicast_port) + + multicast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + multicast_socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) + + multicast_socket.sendto(message, multicast_address) + print("multicast message sent") + + multicast_socket.close() + + \ No newline at end of file