-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathP_Server.py
111 lines (97 loc) · 3.73 KB
/
P_Server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import socket
import threading
# Create a socket object
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to all available interfaces and a port
server_ip = '0.0.0.0'
port = 12345 # Reserve a port for your service
try:
# Bind the socket to the IP address and port
server_socket.bind((server_ip, port))
# Listen for incoming connections
server_socket.listen(5)
print(f"Server listening on {server_ip}:{port}")
except socket.error as e:
print(f"Error binding to {server_ip}:{port}: {e}")
server_socket.close()
exit()
# List to store client connections
clients = []
# Dictionary to store client usernames
usernames = {}
def broadcast(message, sender_client):
"""Broadcasts a message to all clients except the sender."""
for client in clients:
if client != sender_client:
try:
client.send(message.encode('utf-8'))
except:
client.close()
clients.remove(client)
def send_private_message(message, sender_client, recipient_username):
"""Sends a private message to a specific user."""
recipient_client = None
for client, username in usernames.items():
if username == recipient_username:
recipient_client = client
break
if recipient_client:
try:
recipient_client.send(f"Private from {usernames[sender_client]}: {message}".encode('utf-8'))
except:
recipient_client.close()
clients.remove(recipient_client)
else:
sender_client.send(f"User {recipient_username} not found.".encode('utf-8'))
def handle_client(client):
"""Handles a single client connection."""
while True:
try:
message = client.recv(1024).decode('utf-8')
if message:
if message.startswith('/'):
handle_command(message, client)
else:
username = usernames[client]
broadcast(f"{username}: {message}", client)
except:
if client in clients:
clients.remove(client)
username = usernames.pop(client, None)
client.close()
if username:
broadcast(f"{username} has left the chat.", client)
break
def handle_command(command, client):
"""Handles commands from clients."""
parts = command.split(' ', 2)
cmd = parts[0]
if cmd == '/users':
client.send(f"Connected users: {', '.join(usernames.values())}".encode('utf-8'))
elif cmd == '/pm' and len(parts) > 2:
recipient_username = parts[1]
private_message = parts[2]
send_private_message(private_message, client, recipient_username)
else:
client.send("Unknown command or incorrect usage.".encode('utf-8'))
# Accept incoming connections
print("Waiting for connections...")
try:
while True:
client, addr = server_socket.accept()
print(f"Got connection from {addr}")
client.send('Connected to the Group Chat Server!'.encode('utf-8'))
username = client.recv(1024).decode('utf-8')
usernames[client] = username
clients.append(client)
print(f"Username of the client is {username}")
broadcast(f"{username} has joined the chat.", client)
client.send('You are now connected!'.encode('utf-8'))
# Start a new thread for each client
thread = threading.Thread(target=handle_client, args=(client,))
thread.start()
except KeyboardInterrupt:
print("Server is shutting down...")
server_socket.close()
for client in clients:
client.close()