Skip to content
Snippets Groups Projects
Commit 0a3a83ae authored by Michelle Fahrner's avatar Michelle Fahrner
Browse files

Upload New File

parent f5cc6067
No related branches found
No related tags found
1 merge request!1Feat/finalfinal
import socket
import threading
import time
import uuid
import sys
import os
broadcast_ip = '255.255.255.255' #Broadcast-adress in the Network
broadcast_port = 55555 #client sends
broadcast_port2 = 33333 #client listens
heartbeat_client_broadcast_port = 11111 # Defined heartbeat port
#local host information
MY_HOST = socket.gethostname()
MY_IP = socket.gethostbyname(MY_HOST)
#Variables for server heartbeat
is_server_available = True
last_heartbeat = time.time()
processed_message_ids = set() # A set to track the IDs of messages that have already been processed. This helps avoid duplicate processing.
listener_ready = threading.Event()
########################### Start - Receiving MSG ###########################
def listen_server():
"""
Listens for messages broadcasted by the server and processes them.
"""
client_socket2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Create a UDP socket to listen for incoming messages
client_socket2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Enable broadcast mode for the socket
client_socket2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allow the socket to reuse the same address
client_socket2.bind(('', broadcast_port2)) # Bind the socket to the broadcast port and listen on all available IP addresses
"""receives messages from server."""
global message_id # Tracks the ID of the current message
while True:
try:
data, address = client_socket2.recvfrom(4096) # Receive data from the socket
decoded_message = data.decode() # Decode the received message
text = decoded_message
received_uuid, rest_of_text = text.split(":", 1) # Split the message into UUID (unique identifier) and the rest of the text
if received_uuid not in processed_message_ids: # Process the message if it hasn't been processed yet
processed_message_ids.add(received_uuid) # Mark the message as processed
#print(f"Received {data.decode()} from {address}") # Only for Debugging
print(rest_of_text) # Display the message content
#else: ################### Only for debugging
# print("Message ist Doppelt") ################### Only for debugging
except socket.error as e: # Handle and log any errors while listening for messages
print(f"An error occurred while listening: {e}")
continue
########################### End - Receiving MSG ###########################
########################### Start - Sending MSG ###########################
def sender():
"""
Allows the user to compose and send messages to the chat.
"""
global message_id # Tracks the unique ID of each message
message_id = str(uuid.uuid4()) # Generate a unique ID for the user's entry message
nickname = input("Enter your nickname: ") # Prompt the user to enter their nickname
just_nickname= f"{message_id}:{nickname} entered the chat".encode() # Create the initial "entered the chat" message
# create client-socket for broadcast
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client_socket.sendto(just_nickname, (broadcast_ip, broadcast_port)) #Send the "entered the chat" message to the broadcast address
processed_message_ids.add(message_id) # Mark the message ID as processed #######+ Können wir als Rückmeldung auch ausgeben lassen
try:
while True:
message = input("") # Allow the user to enter a message
if message.strip(): # Ensure the message is not empty or whitespace
message_id = str(uuid.uuid4()) # Generate a new unique ID for this message
full_message = f"{message_id}:{nickname}: {message}".encode() # Format the message with the user's nickname and content
client_socket.sendto(full_message, (broadcast_ip, broadcast_port)) # Send the message to the broadcast address
processed_message_ids.add(message_id) # Mark the message ID as processed
except KeyboardInterrupt: ######################whelp....................... Funktioniert das???
# Handle when the user presses Ctrl+C
print(f"\n{nickname} left the chat.")
# Notify others that this client left the chat
message_id = str(uuid.uuid4()) # New message ID
leave_message = f"{nickname} left the chat".encode()
client_socket.sendto(leave_message, (broadcast_ip, broadcast_port))
time.sleep(2) # Wait briefly before closing the socket
client_socket.close() # Close the socket
sys.exit() # Exit the program
########################### End - Sending MSG ###########################
########################### Start - heartbeat ###########################
def listen_to_heartbeat():
"""
Listens for heartbeat messages from the server and updates the timestamp of the last received heartbeat.
"""
global last_heartbeat # Tracks the time of the last received heartbeat
global is_server_available # Indicates whether the server is available
client_heartbeat_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Create a UDP socket to listen for incoming heartbeat messages
client_heartbeat_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Enable broadcast mode for the socket
client_heartbeat_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allow the socket to reuse the same address
client_heartbeat_socket.bind(('', heartbeat_client_broadcast_port)) # Bind the socket to the broadcast port and listen on all available IP addresses
while True:
try: # Wait for incoming heartbeat messages
data, addr = client_heartbeat_socket.recvfrom(1024) # Receive data from the socket
#print("Server heartbeat received.") # Log that the server's heartbeat was received - Only for De bugging
last_heartbeat = time.time() # Update the timestamp for the last received heartbeat
except Exception as e: # Handle and log any errors during data reception
print(f"Error sending data: {e}")
def monitor_heartbeat():
"""
Monitors whether the last heartbeat was received within the timeout period and updates server availability status.
"""
global last_heartbeat # Tracks the time of the last received heartbeat
global is_server_available # Indicates whether the server is available
while True:
time_since_last_heartbeat = time.time() - last_heartbeat # Calculate the time since the last received heartbeat
if time_since_last_heartbeat > 7: # Check if timeout is reached
if is_server_available == True: # If the server was previously available, log that it is now unavailable
print(f"ERROR: Server is Unavailable! Waiting for connection...")
is_server_available = False # Update the server status to unavailable
else: # If the server becomes available again
if is_server_available == False:
is_server_available = True # Update the server status to available
print("Server is up and Running again.")
time.sleep(1) # Check the heartbeat status every second
########################### End - heartbeat ###########################
###############main#################################
if __name__ == "__main__":
# Start listener thread
listen_thread = threading.Thread(target=listen_server)
listen_thread.daemon = True
listen_thread.start()
#listener_ready.wait()
heartbeat_thread = threading.Thread(target=listen_to_heartbeat)
heartbeat_thread.start()
listen_heartbeat_thread = threading.Thread(target=monitor_heartbeat)
listen_heartbeat_thread.start()
sender_thread = threading.Thread(target=sender)
sender_thread.start()
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