diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java index 58d93d59eba78180cf461467af0017a01fee7e0f..94fdb5e9a4f38266a166be160b3ac3a896fe3143 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikClient.java @@ -12,6 +12,7 @@ import java.util.Scanner; * @author tbavlsik */ public class BavlsikClient { + public final static String LOCALHOST = "0:0:0:0:0:0:0:1"; //Local host /** @@ -21,19 +22,36 @@ public class BavlsikClient { public static void main(String[] args) throws Exception { Socket socket = new Socket(LOCALHOST, 2317); - new Thread(new Reader(socket)).start(); + Thread readerThread = new Thread(new Reader(socket)); + readerThread.start(); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { - out.println(scanner.nextLine()); + String msg = scanner.nextLine(); + //If the client wants to exit, type quit and close the socket + if(msg.equalsIgnoreCase("quit")){ + socket.close(); + } + //Checks to see if client or server closed socket, if so, end the program + if (socket.isClosed()) { + System.out.println("Connection closed. Exiting..."); + break; + } + else{ + out.println(msg); + } } + readerThread.join(); } private static class Reader implements Runnable { + private BufferedReader in; + private Socket socket; public Reader(Socket socket) throws IOException { + this.socket = socket; in = new BufferedReader(new InputStreamReader(socket.getInputStream())); } @@ -45,9 +63,15 @@ public class BavlsikClient { System.out.println(message); } } catch (IOException e) { - System.out.println("Error reading from server: " + e); + System.out.println("Disconnected from server."); + } finally { + try { + socket.close(); + } catch (IOException e) { + System.out.println("Error closing socket: " + e); + } } } } - + } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java index 8119fcbe2980ccbcbfb6cebb18c1fd07d5759dfd..ef4978fbe5e757632f5e05033bfe3286abd1cee7 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/BavlsikServer.java @@ -15,7 +15,8 @@ import java.util.HashSet; import java.util.Set; /** - * + * This class establishes a passcode protected chat server. Each client that connects + * is handled by a new thread and messages are broadcast to all connected clients. * @author tbavlsik */ public class BavlsikServer { @@ -27,7 +28,7 @@ public class BavlsikServer { * @param args the command line arguments */ public static void main(String[] args) { - ArrayList passcodes = new ArrayList<>(Arrays.asList(1, 29, 97)); + ArrayList passcodes = new ArrayList<>(Arrays.asList(1, 29, 97));//Very secret passcode, wonder where those numbers came from... System.out.println(BavlsikServer.class.getName() + " has started..."); // it helps debugging to put this on console first try (ServerSocket listener = new ServerSocket(2317)) { while (true) { @@ -46,6 +47,7 @@ public class BavlsikServer { int pass = Integer.parseInt(passInput.trim()); + //Validate the client entered passcode if (passcodes.contains(pass)) { ps.println("Welcome " + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " to the group chat!"); for (PrintWriter writer : clientWriters) { @@ -53,8 +55,9 @@ public class BavlsikServer { } ps.flush(); handler.start(); - } else { + } else {//Kick the client from the server. ps.println("Not a valid passcode."); + System.out.println(remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " entered an incorrect passcode; disconnecting."); handler.socket.close(); } } @@ -88,7 +91,7 @@ public class BavlsikServer { synchronized (clientWriters) { clientWriters.add(out); } - + //Read in the message sent by the client and then send it to all other connected clients String message; while ((message = in.readLine()) != null) { String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort() + ": " + message; @@ -100,6 +103,9 @@ public class BavlsikServer { } catch (IOException e) { System.out.println("Error handling client: " + e); } finally { + //if a client disconnects or is kicked from the server, close the socket and broadcast the message to the chat + String disconnectMessage = (socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort() + " has disconnected."); + System.out.println(disconnectMessage); try { socket.close(); } catch (IOException e) { @@ -109,6 +115,9 @@ public class BavlsikServer { synchronized (clientWriters) { clientWriters.remove(out); } + for (PrintWriter writer : clientWriters) { + writer.println(disconnectMessage); + } } } } diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md index 867191babbb74e9d2677211dd49749d6e0b85f91..448a0bf1e467203f8eb4e28081fbf90944d841f2 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Bavlsik/README.md @@ -3,8 +3,18 @@ *** ## Description -Modification of TcpExample3 and adding some code to implement a chat room with multiple clients. +Modification of TcpExample3 and adding some code to implement a passcode protected +chat room with multiple clients. -The 'BavlsikServer' class sets up a server that listens for incoming client connections on port 2317. When a client connects, the server creates a new handler thread for managing communication with that client. Each client's messages are broadcast to all other connected clients. +The 'BavlsikServer' class sets up a server that listens for incoming client connections +on port 2317. When a client connects, the server creates a new handler thread for +managing communication with that client. After the connection is established, +the server prompts the client for a passcode. If the client enters a valid passcode +they are added to teh chat room where each client's messages are broadcast to all +other connected clients. If the passcode is entered incorrectly, they client is +disconnected from the server. If a client enters 'quit' they disconnect from the server. -The 'BavlsikClient' class connects to a server running on localhost at port 2317. It sends user input from the console to the server and displays messages received from the server. \ No newline at end of file +The 'BavlsikClient' class connects to a server running on localhost at port 2317. +If the client enters a correct passcode, they are added to the chatroom, if it is +incorrect they are disconnecte. The client then sends user input from the console +to the server and displays messages received from the server. \ No newline at end of file