Skip to content
Snippets Groups Projects
Select Git revision
  • eray
  • master default protected
  • david
  • artem
  • Benedikt
5 results

reference.txt

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    server.py 7.53 KiB
    import multiprocessing
    import socket
    import threading
    import json
    
    class Server(multiprocessing.Process):
        server_address = '127.0.0.1'
        client_cache_key_offset = 0
        local_servers_cache = dict()
        local_clients_cache = dict()
    
        def __init__(self, client_address, server_id, server_port, server_cache, clients_cache):
            super(Server, self).__init__()
            self.client_address = client_address
            self.server_id = server_id
            self.server_port = server_port
            self.local_servers_cache = server_cache
            self.local_clients_cache = clients_cache
            self.run( )
    
        def run(self):
            print(self.server_id+": "+"Up and running")
            #print("SERVER", self.server_id)
            if self.server_id == "MAIN":
                client_listener_thread = threading.Thread(target=self.listen_for_clients)
                client_listener_thread.start()
    
            else:
                self.send_reply_to_client()
    
                cache_update_listener_thread = threading.Thread(target=self.listen_for_cache_update)
                client_message_listener_thread = threading.Thread(target=self.listen_for_client_messages)
    
                cache_update_listener_thread.start()
                client_message_listener_thread.start()
    
    
        def send_reply_to_client(self):
            message = 'Hi ' + self.client_address[0] + ' this is your chat-group server ' + self.server_id + '. (' + self.server_address + ':' + str(self.server_port) + ')'
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            server_socket.connect((self.server_address, self.server_port))
            server_socket.sendto(str.encode(message), self.client_address)
            server_socket.close()
    
        def listen_for_clients(self):
            if self.server_id == "MAIN":
                BROADCAST_PORT = 5970
    
                # Local host information
                MY_HOST = socket.gethostname()
                MY_IP = socket.gethostbyname(MY_HOST)
    
                # Create a UDP socket
                listen_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                # Set the socket to broadcast and enable reusing addresses
                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))
    
                print(self.server_id+": "+"Listening to client register broadcast messages")
    
                while True:
                    data, addr = listen_socket.recvfrom(1024)
                    if data:
                        message = data.decode('utf-8')
                        print(self.server_id+": "+"Received client register broadcast message:", message)
                        splitted = message.split("_")
                        if (splitted[0] == 'register'):
                            self.register_client(splitted[1].upper(), addr)
      
                            update_cache_thread = threading.Thread(target=self.updateCacheList)
                            if update_cache_thread.is_alive:
                                update_cache_thread.run()
                            else:
                                update_cache_thread.start()
                            
    
        # Register client. Check if group already exists. If true, add client to existing list, otherwise create new server.    
        def register_client(self, group, addr):
            if group not in self.local_servers_cache:
                print(self.server_id+": "+"Group "+group+" doesn't exist yet. Creating group..")
                server_adress = self.create_server(group, addr) 
                
                group_count = self.filter_groups(group)
    
                self.local_servers_cache[group] = server_adress
                self.client_cache_key_offset = group_count + 1
                client_cache_key = group + str(self.client_cache_key_offset)
                self.local_clients_cache[client_cache_key] = addr
        
            else:
                print(self.server_id+": "+"Group "+group+" already exists")
                client_count = self.filter_clients(group)
                self.client_cache_key_offset = client_count + 1
                client_cache_key = group + str(self.client_cache_key_offset)
                self.local_clients_cache[client_cache_key] = addr
    
         
        def filter_groups(self, group):
            group_count = 0
            for key in self.local_servers_cache:
                if group in key:
                    group_count = group_count + 1
            
            return group_count
        
        def filter_clients(self, group):
            client_count = 0
            for key in self.local_clients_cache:
                if group == key[0]:
                    client_count = client_count + 1
                    
            return client_count
            
        # Create and run new server 
        def create_server(self, server_id, client_address):
            
            self.server_port = self.server_port + 1
    
            new_server = Server(client_address, server_id, self.server_port, self.local_servers_cache, self.local_clients_cache)
    
            #new_server.send_reply_to_client()
    
            return self.server_port
    
        def updateCacheList(self):
            PORT = 5980
            servers_cache_as_string = json.dumps(self.local_servers_cache, indent=2).encode('utf-8')
            clients_cache_as_string = json.dumps(self.local_clients_cache, indent=2).encode('utf-8')
            separator = "_"
    
            MSG = servers_cache_as_string + separator.encode('utf-8') + clients_cache_as_string
    
            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.close()
    
        def listen_for_cache_update(self):
            BROADCAST_PORT = 5980
    
            # Local host information
            MY_HOST = socket.gethostname()
            MY_IP = socket.gethostbyname(MY_HOST)
    
            # Create a UDP socket
            listen_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            # Set the socket to broadcast and enable reusing addresses
            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))
    
            print(self.server_id+": "+"Listening to cache update broadcast messages")
    
            while True:
                data, addr = listen_socket.recvfrom(1024)
                if data:
                    message = data.decode('utf-8')
                    print(self.server_id+": "+"Received cache update broadcast message:")
                    splitted = message.split("_")
                    server_cache_json = json.loads(splitted[0])
                    client_cache_json = json.loads(splitted[1])
                    self.local_servers_cache = server_cache_json
                    self.local_clients_cache = client_cache_json
    
                    print(self.local_servers_cache)
                    print(self.local_clients_cache)
    
        def listen_for_client_messages(self):
    
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.bind((self.server_address, self.server_port))
            server_socket.listen()
    
            print(self.server_id+": "+"Group-chat server is listening for client messages at port: ", self.server_port)
    
            while True:
                conn, addr = server_socket.accept()
                print(f"Connection established with {addr}")
    
                data = conn.recv(1024)
                print(f"Received message from client: {data.decode('utf-8')}")
    
                response = "Hello, client! I received your message."
                conn.sendall(bytes(response, 'utf-8'))
    
                conn.close()