Skip to content
Snippets Groups Projects
Commit 0513da57 authored by owner's avatar owner
Browse files

Merge origin/master

parents 9f19f3c2 13502071
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,7 @@ import java.util.Scanner; ...@@ -12,6 +12,7 @@ import java.util.Scanner;
* @author tbavlsik * @author tbavlsik
*/ */
public class BavlsikClient { public class BavlsikClient {
public final static String LOCALHOST = "0:0:0:0:0:0:0:1"; //Local host public final static String LOCALHOST = "0:0:0:0:0:0:0:1"; //Local host
/** /**
...@@ -21,19 +22,36 @@ public class BavlsikClient { ...@@ -21,19 +22,36 @@ public class BavlsikClient {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Socket socket = new Socket(LOCALHOST, 2317); 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); PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) { 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 static class Reader implements Runnable {
private BufferedReader in; private BufferedReader in;
private Socket socket;
public Reader(Socket socket) throws IOException { public Reader(Socket socket) throws IOException {
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} }
...@@ -45,9 +63,15 @@ public class BavlsikClient { ...@@ -45,9 +63,15 @@ public class BavlsikClient {
System.out.println(message); System.out.println(message);
} }
} catch (IOException e) { } 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);
}
} }
} }
} }
} }
...@@ -9,14 +9,18 @@ import java.io.PrintWriter; ...@@ -9,14 +9,18 @@ import java.io.PrintWriter;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; 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 * @author tbavlsik
*/ */
public class BavlsikServer { public class BavlsikServer {
// the set clientWriters contains form all sockets the active PrintStream // the set clientWriters contains form all sockets the active PrintStream
private static Set<PrintWriter> clientWriters = new HashSet<>(); private static Set<PrintWriter> clientWriters = new HashSet<>();
...@@ -24,25 +28,40 @@ public class BavlsikServer { ...@@ -24,25 +28,40 @@ public class BavlsikServer {
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(String[] args) { public static void main(String[] args) {
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 System.out.println(BavlsikServer.class.getName() + " has started..."); // it helps debugging to put this on console first
try (ServerSocket listener = new ServerSocket(2317)) { try (ServerSocket listener = new ServerSocket(2317)) {
while (true) { while (true) {
Handler handler = new Handler(listener.accept()); // create a new thread writing and reading to and from the new socket Handler handler = new Handler(listener.accept()); // create a new thread writing and reading to and from the new socket
OutputStream os = handler.socket.getOutputStream(); OutputStream os = handler.socket.getOutputStream();
PrintStream ps = new PrintStream(os); PrintStream ps = new PrintStream(os);
InetAddress remoteAddress = handler.socket.getInetAddress(); InetAddress remoteAddress = handler.socket.getInetAddress();
int remotePort = handler.socket.getPort(); int remotePort = handler.socket.getPort();
String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " has connected to the server."; String message = remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " has connected to the server.";
System.out.println(message); System.out.println(message);
ps.println("Welcome " + remoteAddress.getHostName() + "=" + remoteAddress.getHostAddress() + ", " + remotePort + " to the group chat!"); BufferedReader reader = new BufferedReader(new InputStreamReader(handler.socket.getInputStream()));
for (PrintWriter writer : clientWriters) { ps.println("Enter a passcode:");
String passInput = reader.readLine(); // read the entire line as a string
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) {
writer.println(message); writer.println(message);
} }
ps.flush(); ps.flush();
handler.start(); handler.start();
} 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();
}
} }
}catch (IOException e) { } catch (IOException e) {
System.err.println("Problem with " + BavlsikServer.class.getName() + " networking: " + e); System.err.println("Problem with " + BavlsikServer.class.getName() + " networking: " + e);
// Provide more helpful information to user if exception occurs due to running twice at one time // Provide more helpful information to user if exception occurs due to running twice at one time
...@@ -50,10 +69,11 @@ public class BavlsikServer { ...@@ -50,10 +69,11 @@ public class BavlsikServer {
System.err.println("*** Be sure to stop any other running instances of programs using this port!"); System.err.println("*** Be sure to stop any other running instances of programs using this port!");
} }
} }
} }
private static class Handler extends Thread { private static class Handler extends Thread {
public final Socket socket; public final Socket socket;
private PrintWriter out; private PrintWriter out;
private BufferedReader in; private BufferedReader in;
...@@ -71,10 +91,10 @@ public class BavlsikServer { ...@@ -71,10 +91,10 @@ public class BavlsikServer {
synchronized (clientWriters) { synchronized (clientWriters) {
clientWriters.add(out); clientWriters.add(out);
} }
//Read in the message sent by the client and then send it to all other connected clients
String message; String message;
while ((message = in.readLine()) != null) { while ((message = in.readLine()) != null) {
String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort()+ ": " + message; String outputMessage = socket.getInetAddress().getHostName() + "=" + socket.getInetAddress().getHostAddress() + ", " + socket.getPort() + ": " + message;
System.out.println(outputMessage); System.out.println(outputMessage);
for (PrintWriter writer : clientWriters) { for (PrintWriter writer : clientWriters) {
writer.println(outputMessage); writer.println(outputMessage);
...@@ -83,6 +103,9 @@ public class BavlsikServer { ...@@ -83,6 +103,9 @@ public class BavlsikServer {
} catch (IOException e) { } catch (IOException e) {
System.out.println("Error handling client: " + e); System.out.println("Error handling client: " + e);
} finally { } 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 { try {
socket.close(); socket.close();
} catch (IOException e) { } catch (IOException e) {
...@@ -92,8 +115,11 @@ public class BavlsikServer { ...@@ -92,8 +115,11 @@ public class BavlsikServer {
synchronized (clientWriters) { synchronized (clientWriters) {
clientWriters.remove(out); clientWriters.remove(out);
} }
for (PrintWriter writer : clientWriters) {
writer.println(disconnectMessage);
}
} }
} }
} }
} }
...@@ -3,8 +3,18 @@ ...@@ -3,8 +3,18 @@
*** ***
## Description ## 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. The 'BavlsikClient' class connects to a server running on localhost at port 2317.
\ No newline at end of file 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment