Skip to content
Snippets Groups Projects
Commit 7665d11f authored by Quoc Nguyen Dao's avatar Quoc Nguyen Dao
Browse files

Server-Server Discovery

parent 4ca12c6a
1 merge request!2leader election und heartbeat
......@@ -65,6 +65,26 @@ class Client():
except socket.timeout:
pass
def discover_group_members(self):
# Send a broadcast message to discover group members
group_discovery_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
group_discovery_socket.settimeout(3) # Set timeout to 3 seconds
group_discovery_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
group_discovery_socket.sendto(str.encode("Any group members here?"), ('<broadcast>', BROADCAST_PORT))
try:
while True:
data, addr = group_discovery_socket.recvfrom(1024)
if data:
group_member_IP = data.decode()
if group_member_IP != MY_IP and group_member_IP not in self.group_members:
self.group_members[group_member_IP] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.printwt(f'New group member found: {group_member_IP}')
# Respond to the new member with own IP
group_discovery_socket.sendto(str.encode(MY_IP), (group_member_IP, BROADCAST_PORT))
except socket.timeout:
group_discovery_socket.close()
def receive_messages(self):
while True:
try:
......@@ -82,6 +102,11 @@ class Client():
if __name__ == "__main__":
client = Client()
# Start a thread to discover group members
discovery_thread = threading.Thread(target=client.discover_group_members)
discovery_thread.start()
# Start the thread to send and receive messages
thread1 = threading.Thread(target = client.BroadcastSendAndReceive)
thread1.start()
thread1.join()
\ No newline at end of file
import socket
import threading
from datetime import datetime
import time
# Listening port
BROADCAST_PORT = 5973
......@@ -11,13 +12,22 @@ MY_IP = socket.gethostbyname(MY_HOST)
class Server():
def __init__(self):
self.group_members = {} # Dictionary to store group members with their IPs as keys
self.leader_IP = '' # fix the leader IP
self.clients = []
def printwt(self, msg):
current_date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f'[{current_date_time}] {msg}')
def print_group_members(self):
self.printwt("Current group members:")
for member, timestamp in self.group_members.items():
self.printwt(f'{member} (joined at {timestamp})')
# Listen to client broadcast (request) and reply with Server IP
def ListenForClientAndReply(self):
# Create a UDP socket
......@@ -38,12 +48,12 @@ class Server():
self.printwt(data.decode())
# if Iam the leader, answer the client including my IP
# if MY_IP == self.leader_IP:
if data:
if MY_IP == self.leader_IP:
reply_message = MY_IP
listen_socket.sendto(str.encode(reply_message), addr)
self.printwt('Replied my IP to new client')
def handle_client(self, client_socket, client_address):
self.clients.append(client_socket)
......@@ -58,6 +68,7 @@ class Server():
self.clients.remove(client_socket)
break
def broadcast(self, message, sender_socket):
for client in self.clients:
try:
......@@ -67,13 +78,44 @@ class Server():
self.clients.remove(client)
def announce_leader(self):
# Send a broadcast message to determine the leader
leader_broadcast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
leader_broadcast_socket.settimeout(3) # Set timeout to 3 seconds
leader_broadcast_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
leader_broadcast_socket.sendto(str.encode("Who is the leader?"), ('<broadcast>', BROADCAST_PORT))
try:
data, addr = leader_broadcast_socket.recvfrom(1024)
if data:
self.leader_IP = addr[0]
self.group_members[self.leader_IP] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.printwt(f'Leader elected: {self.leader_IP}')
except socket.timeout:
# If no response received, assume this server is the leader
self.leader_IP = MY_IP
self.group_members[self.leader_IP] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.printwt(f'I am the first server and leader: {self.leader_IP}')
leader_broadcast_socket.close()
# starting all simultaneously working procedures
if __name__== '__main__':
server = Server()
# Start a thread to announce the leader
leader_thread = threading.Thread(target=server.announce_leader)
leader_thread.start()
# Start the thread to listen for client broadcasts
thread1 = threading.Thread(target = server.ListenForClientAndReply)
thread1.start()
# Start a thread to periodically print the group members
print_group_thread = threading.Thread(target=server.print_group_members)
print_group_thread.start()
# Socket erstellen und binden
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((MY_IP, 5555))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment