Select Git revision
reference.txt
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()