Skip to content

Commit db71147

Browse files
committed
Fix leave and exit
2 parents 82e05e7 + 9697dfe commit db71147

File tree

3 files changed

+132
-86
lines changed

3 files changed

+132
-86
lines changed

GUI/src/main/java/org/example/client.java

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,7 @@ public static void main(String argv[]) {
2828
client newClient = new client();
2929
newClient.connect();
3030
newClient.init();
31-
//newClient.clientGUI = new GUI();
32-
//newClient.clientGUI.init();
33-
//newClient.close();
34-
}
35-
catch (Exception e) {
31+
} catch (Exception e) {
3632
System.out.println("Exception occurred in client main:" + e);
3733
}
3834
}
@@ -54,34 +50,32 @@ public void init() {
5450
}
5551
}
5652

57-
public void close() {
58-
try {
59-
controlSocket.close();
60-
} catch (IOException e) {
61-
throw new RuntimeException(e);
62-
}
63-
sendMsgThread.interrupt();
64-
rcvMsgThread.interrupt();
65-
}
66-
6753
/* Connect to the server */
68-
public void connect() {
69-
try {
70-
// establish the control socket
71-
controlSocket = new Socket("localhost", 6789);
72-
73-
// get references to the socket input and output streams
74-
InputStreamReader isr = new InputStreamReader(controlSocket.getInputStream());
75-
controlReader = new BufferedReader(isr);
76-
controlWriter = new DataOutputStream(controlSocket.getOutputStream());
77-
}
78-
catch (UnknownHostException ex) {
79-
System.out.println("UnknownHostException during connection attempt: " + ex);
80-
}
81-
catch (IOException ex) {
82-
System.out.println("IOException during connection attempt: " + ex);
83-
}
84-
} /* end client.connect() */
54+
public void connect() {
55+
try {
56+
controlSocket = new Socket("localhost", 6789);
57+
controlReader = new BufferedReader(new InputStreamReader(controlSocket.getInputStream()));
58+
controlWriter = new DataOutputStream(controlSocket.getOutputStream());
59+
} catch (UnknownHostException ex) {
60+
System.out.println("UnknownHostException during connection attempt: " + ex);
61+
close();
62+
} catch (IOException ex) {
63+
System.out.println("IOException during connection attempt: " + ex);
64+
close();
65+
}
66+
}
67+
68+
public void close() {
69+
try {
70+
if (controlSocket != null) controlSocket.close();
71+
if (controlReader != null) controlReader.close();
72+
if (controlWriter != null) controlWriter.close();
73+
} catch (IOException e) {
74+
System.err.println("Error closing resources: " + e.getMessage());
75+
}
76+
if (sendMsgThread != null) sendMsgThread.interrupt();
77+
if (rcvMsgThread != null) rcvMsgThread.interrupt();
78+
}
8579

8680
final class TcpSend implements Runnable {
8781
Socket socket; // reference to connection socket
@@ -116,6 +110,10 @@ public void sendMsg() {
116110
System.out.println("exiting client program");
117111
break;
118112
}
113+
response = controlReader.readLine();
114+
if (response != null) {
115+
System.out.println(response);
116+
}
119117
}
120118
catch (IOException ex) {
121119
System.out.println("IOException occured during send message attempt: " + ex);

client.py

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,57 @@
22
import threading
33

44
def receive_messages():
5-
while True:
5+
global running
6+
while running:
67
try:
78
message = client.recv(1024).decode('utf-8')
9+
if message.startswith("exit"):
10+
running = False
11+
break
12+
813
print(message)
9-
except:
10-
print('An error occurred!')
11-
client.close()
14+
except Exception as e:
15+
print(f'An error occurred: {e}')
1216
break
1317

1418
def send_messages():
15-
while True:
19+
global running
20+
21+
while running:
1622
try:
1723
command = input()
18-
19-
# Send commands to the server
2024
client.send(command.encode('utf-8'))
21-
msg = client.recv(1024).decode('utf-8')
22-
if msg[0] == "exit":
23-
print("Exiting the group chat")
24-
client.close()
25-
break
26-
except:
27-
print('Exiting the group chat')
28-
client.close()
25+
except Exception as e:
26+
print(f'Exiting the group chat {e}')
2927
break
3028

3129
if __name__ == "__main__":
32-
host = 'localhost'
33-
port = 6789
30+
running = True
31+
s = ""
32+
while True:
33+
s = input("%connect [address] [port]: To connect to the server\n")
34+
35+
if not s.startswith("%connect"):
36+
print("invalid inputs")
37+
continue
38+
else:
39+
break
40+
41+
s = s.split(" ")
42+
host, port = s[1], int(s[2])
3443
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3544
client.connect((host, port))
3645

3746
# Start receiving messages in a separate thread
3847
receive_thread = threading.Thread(target=receive_messages)
3948
receive_thread.start()
4049

41-
# Start sending messages (commands) in the main thread
50+
# Start sending messages in a separate thread
4251
send_thread = threading.Thread(target=send_messages)
4352
send_thread.start()
53+
54+
# Join threads to ensure proper exit
55+
receive_thread.join()
56+
send_thread.join()
57+
58+
client.close()

server.py

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import socket
22
import threading
33
import time
4+
import signal
5+
6+
# Flag to control server loop
7+
running = True
48

59
def broadcast(message):
610
for client in clients:
@@ -11,7 +15,8 @@ def broadcast_group(message, group_id):
1115
client.send(message)
1216

1317
def handle_client(client):
14-
while True:
18+
global running
19+
while running:
1520
try:
1621
message = client.recv(1024).decode('utf-8')
1722
if message:
@@ -60,6 +65,7 @@ def handle_client(client):
6065
client.send('Invalid command format. Use "%connect [address] [port]\n".'.encode('utf-8'))
6166

6267
elif command == "%post":
68+
6369
subject = message[1]
6470
content = " ".join(message[2:])
6571

@@ -78,12 +84,14 @@ def handle_client(client):
7884
client.send(f"Users in the group:\n{user_list}\n".encode('utf-8'))
7985

8086
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]
8392
clients.remove(client)
84-
broadcast(f'{username} has left the chat room!\n'.encode('utf-8'))
8593
client.send("You left the chat room!\n".encode('utf-8'))
86-
client.close()
94+
8795
elif command == '%message':
8896
msg_id = int(message[1])
8997

@@ -102,11 +110,12 @@ def handle_client(client):
102110
client.send("You are disconnected from the server!\n".encode('utf-8'))
103111
client.send("exit".encode("utf-8"))
104112
client.close()
113+
break
105114
elif command == "%groups":
106115
response = f"Here're all the group available: \n {' '.join([str(i) for i in range(GROUPS)])}"
107116

108117
client.send(response.encode("utf-8"))
109-
elif command == "%groupjoin":
118+
elif command == "%groupsjoin":
110119
if len(message) < 2:
111120
client.send('Invalid command format. Try again!\n'.encode('utf-8'))
112121
continue
@@ -126,7 +135,6 @@ def handle_client(client):
126135
if client in usernames:
127136
username = usernames[client]
128137

129-
130138
client.send(f"User {username} join group {group_id}".encode("utf-8"))
131139
elif command == "%groupusers":
132140
if len(message) < 2:
@@ -211,14 +219,54 @@ def handle_client(client):
211219
# print(e)
212220
print("Exception occurred in server: " + e)
213221
break
214-
222+
223+
# Function to handle SIGINT
224+
def signal_handler(sig, frame):
225+
global running
226+
print("\nServer is shutting down...")
227+
running = False
228+
server.close()
229+
for client in clients:
230+
client.close()
231+
print("Server shutdown complete.")
232+
215233
def run_server():
234+
global running
216235
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!
222270
Available commands:
223271
%connect [address] [port]: Connect to a different server
224272
%join [username]: Join with the username
@@ -235,29 +283,14 @@ def run_server():
235283
%groupusers [group ID]: Retrieve a list of users in the given group
236284
%groupmessage [group ID] [message ID]: retrieve the content of an earlier post if you belong to that group
237285
%groupleave [group ID]: Leave the current group if client is in that group
238-
""".encode('utf-8'))
286+
"""
239287

240-
thread = threading.Thread(target=handle_client, args=(client,))
241-
thread.start()
288+
# Register the signal handler
289+
signal.signal(signal.SIGINT, signal_handler)
242290

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-
263291
run_server()
292+
293+
294+
295+
296+

0 commit comments

Comments
 (0)