Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
Distributed-Systems
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Katharina Willig
Distributed-Systems
Commits
0a3a83ae
Commit
0a3a83ae
authored
4 months ago
by
Michelle Fahrner
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
f5cc6067
No related branches found
No related tags found
1 merge request
!1
Feat/finalfinal
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
2025-01-10_Client_V6.py
+136
-0
136 additions, 0 deletions
2025-01-10_Client_V6.py
with
136 additions
and
0 deletions
2025-01-10_Client_V6.py
0 → 100644
+
136
−
0
View file @
0a3a83ae
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
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment