1
1
import socket
2
2
import threading
3
3
import time
4
+ import signal
5
+
6
+ # Flag to control server loop
7
+ running = True
4
8
5
9
def broadcast (message ):
6
10
for client in clients :
@@ -11,7 +15,8 @@ def broadcast_group(message, group_id):
11
15
client .send (message )
12
16
13
17
def handle_client (client ):
14
- while True :
18
+ global running
19
+ while running :
15
20
try :
16
21
message = client .recv (1024 ).decode ('utf-8' )
17
22
if message :
@@ -60,6 +65,7 @@ def handle_client(client):
60
65
client .send ('Invalid command format. Use "%connect [address] [port]\n ".' .encode ('utf-8' ))
61
66
62
67
elif command == "%post" :
68
+
63
69
subject = message [1 ]
64
70
content = " " .join (message [2 :])
65
71
@@ -78,12 +84,14 @@ def handle_client(client):
78
84
client .send (f"Users in the group:\n { user_list } \n " .encode ('utf-8' ))
79
85
80
86
elif command == '%leave' :
81
- username = usernames [client ]
82
- del usernames [client ]
87
+ if client in usernames :
88
+ username = usernames [client ]
89
+
90
+ broadcast (f'{ username } has left the chat room!\n ' .encode ('utf-8' ))
91
+ del usernames [client ]
83
92
clients .remove (client )
84
- broadcast (f'{ username } has left the chat room!\n ' .encode ('utf-8' ))
85
93
client .send ("You left the chat room!\n " .encode ('utf-8' ))
86
- client . close ()
94
+
87
95
elif command == '%message' :
88
96
msg_id = int (message [1 ])
89
97
@@ -102,11 +110,12 @@ def handle_client(client):
102
110
client .send ("You are disconnected from the server!\n " .encode ('utf-8' ))
103
111
client .send ("exit" .encode ("utf-8" ))
104
112
client .close ()
113
+ break
105
114
elif command == "%groups" :
106
115
response = f"Here're all the group available: \n { ' ' .join ([str (i ) for i in range (GROUPS )])} "
107
116
108
117
client .send (response .encode ("utf-8" ))
109
- elif command == "%groupjoin " :
118
+ elif command == "%groupsjoin " :
110
119
if len (message ) < 2 :
111
120
client .send ('Invalid command format. Try again!\n ' .encode ('utf-8' ))
112
121
continue
@@ -126,7 +135,6 @@ def handle_client(client):
126
135
if client in usernames :
127
136
username = usernames [client ]
128
137
129
-
130
138
client .send (f"User { username } join group { group_id } " .encode ("utf-8" ))
131
139
elif command == "%groupusers" :
132
140
if len (message ) < 2 :
@@ -211,14 +219,54 @@ def handle_client(client):
211
219
# print(e)
212
220
print ("Exception occurred in server: " + e )
213
221
break
214
-
222
+
223
+ # Function to handle SIGINT
224
+ def signal_handler (sig , frame ):
225
+ global running
226
+ print ("\n Server is shutting down..." )
227
+ running = False
228
+ server .close ()
229
+ for client in clients :
230
+ client .close ()
231
+ print ("Server shutdown complete." )
232
+
215
233
def run_server ():
234
+ global running
216
235
print ("Server started. Waiting for connections..." )
217
- while True :
218
- client , address = server .accept ()
219
- clients .append (client )
220
- print (f'Connection established with { address } ' )
221
- client .send ("""Welcome to the chat room!
236
+ while running :
237
+ try :
238
+ client , address = server .accept ()
239
+ clients .append (client )
240
+ print (f'Connection established with { address } ' )
241
+ client .send (welcome_message .encode ('utf-8' ))
242
+ thread = threading .Thread (target = handle_client , args = (client ,))
243
+ thread .start ()
244
+ except OSError :
245
+ # This exception will be raised when the server socket is closed
246
+ break
247
+
248
+ if __name__ == "__main__" :
249
+ host = 'localhost'
250
+ port = 6789
251
+ GROUPS = 5
252
+
253
+ server = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
254
+ server .bind ((host , port ))
255
+ server .listen ()
256
+
257
+ clients = [] # List to keep track of clients
258
+ usernames = {} # client -> username
259
+ messages = [] # messages
260
+ group_messages = {} # group -> messages
261
+ group_users = {} # group -> client
262
+
263
+ for i in range (GROUPS ):
264
+ group_users [i ] = []
265
+ group_messages [i ] = []
266
+
267
+ # Define welcome message outside the loop
268
+ welcome_message = """
269
+ Welcome to the chat room!
222
270
Available commands:
223
271
%connect [address] [port]: Connect to a different server
224
272
%join [username]: Join with the username
@@ -235,29 +283,14 @@ def run_server():
235
283
%groupusers [group ID]: Retrieve a list of users in the given group
236
284
%groupmessage [group ID] [message ID]: retrieve the content of an earlier post if you belong to that group
237
285
%groupleave [group ID]: Leave the current group if client is in that group
238
- """ . encode ( 'utf-8' ))
286
+ """
239
287
240
- thread = threading . Thread ( target = handle_client , args = ( client ,))
241
- thread . start ( )
288
+ # Register the signal handler
289
+ signal . signal ( signal . SIGINT , signal_handler )
242
290
243
- if __name__ == "__main__" :
244
- host = 'localhost'
245
- port = 6789
246
- GROUPS = 5
247
-
248
- server = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
249
- server .bind ((host , port ))
250
- server .listen ()
251
-
252
-
253
- clients : list [type (socket )] = []
254
- usernames = {} # client -> username
255
- messages = [] # messages
256
- group_messages = {} # group -> messages
257
- group_users = {} # group -> client
258
-
259
- for i in range (GROUPS ):
260
- group_users [i ] = []
261
- group_messages [i ] = []
262
-
263
291
run_server ()
292
+
293
+
294
+
295
+
296
+
0 commit comments