diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Client.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Client.java new file mode 100644 index 0000000000000000000000000000000000000000..e292bcb73d1d21a1823e19024fde4f7c9a75fc3d --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Client.java @@ -0,0 +1,96 @@ +package TcpExamples; + +import java.io.*; +import java.net.*; +//import java.time.LocalTime; // conversion? + +/** + * This client program establishes a socket connection to the + * {@link TcpExample4DispatchServer}, then checks how long it takes to read the + * single line it expects as a server response. No fancy footwork here, it is + * pretty simple and similar to {@link TcpExample3Client}. + * + * @see TcpExample4DispatchServer + * @see TcpExample4HandlerThread + * + * @see + * <a href="../../../src/TcpExamples/TcpExample4TerminalLog.txt" target="blank">TcpExample4TerminalLog.txt</a> + * @see + * <a href="../../../src/TcpExamples/TcpExample4SequenceDiagram.png" target="blank">TcpExample4SequenceDiagram.png</a> + * @see + * <a href="../../../src/TcpExamples/TcpExample4SequenceSketch.png" target="blank">TcpExample4SequenceSketch.png</a> + * + * @author Don McGregor + * @author Don Brutzman + * @author MV3500 class + */ +public class YuHW2Client { + + /** + * Default constructor + */ + public YuHW2Client() { + // default constructor + } + static String DESTINATION_HOST = "localhost"; + static int MAX_LOOP_COUNT = 4; + + /** + * Program invocation, execution starts here + * + * @param args command-line arguments + */ + public static void main(String[] args) { + try { + System.out.println(YuHW2Client.class.getName() + " start, loop " + MAX_LOOP_COUNT + " times"); + System.out.println("======================================================="); + for (int loopCount = 1; loopCount <= MAX_LOOP_COUNT; loopCount++) { + System.out.println(YuHW2Client.class.getName() + " creating new socket #" + loopCount + "..."); + + long startTime = System.currentTimeMillis(); + + Socket socket = new Socket(DESTINATION_HOST, 2317); + + PrintStream ps = new PrintStream(socket.getOutputStream()); + BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + // Knock Knock joke sequence + ps.println("Knock Knock"); + ps.flush(); + System.out.println("Client: Knock Knock"); + + String serverResponse = br.readLine(); // blocks + System.out.println("Server: " + serverResponse); + + if ("Who's there?".equals(serverResponse)) { + ps.println("Hatch"); + ps.flush(); + System.out.println("Client: Hatch"); + } + + serverResponse = br.readLine(); + System.out.println("Server: " + serverResponse); + + if ("Hatch who?".equals(serverResponse)) { + ps.println("God Bless You!"); + ps.flush(); + System.out.println("Client: God Bless You!"); + } + + long readTime = System.currentTimeMillis(); + long timeLength = readTime - startTime; + + System.out.println(YuHW2Client.class.getName() + ": time msec required for sequence=" + timeLength); + System.out.println("======================================================="); + socket.close(); + } + System.out.println(YuHW2Client.class.getName() + " complete"); + } catch (IOException e) { + System.out.println("Problem with " + YuHW2Client.class.getName() + " networking:"); + System.out.println("Error: " + e); + if (e instanceof java.net.BindException) { + System.out.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + } +} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2HandlerThread.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2HandlerThread.java new file mode 100644 index 0000000000000000000000000000000000000000..606510f2d79710dc076a6a09d54278eaae1e8973 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2HandlerThread.java @@ -0,0 +1,102 @@ +package TcpExamples; + +import java.io.*; +import java.net.*; + +/** + * <p> + * This utility class supports the {@link TcpExample4DispatchServer} program, + * handling all programming logic needed for a new socket connection + * to run in a thread of its own. This is the server + * portion as well, so we artificially invent what happens + * if the server can't respond to a connection for several seconds. + * </p> + * <p> + * Warning: do not run this class! It is created and used automatically by {@link TcpExample4DispatchServer} at run time. + * </p> + * + * @see TcpExample4Client + * @see TcpExample4DispatchServer + * + * @see <a href="../../../src/TcpExamples/TcpExample4TerminalLog.txt" target="blank">TcpExample4TerminalLog.txt</a> + * @see <a href="../../../src/TcpExamples/TcpExample4SequenceDiagram.png" target="blank">TcpExample4SequenceDiagram.png</a> + * @see <a href="../../../src/TcpExamples/TcpExample4SequenceSketch.png" target="blank">TcpExample4SequenceSketch.png</a> + * + * @author Don McGregor + * @author Don Brutzman + * @author MV3500 class + */ +public class YuHW2HandlerThread extends Thread +{ + /** The socket connection to a client */ + Socket socket; + + /** + * The thread constructor creates the socket from a ServerSocket, waiting for the client to connect, + * and passes that socket when constructing the thread responsible for handling the connection. + * + * @param socket The socket connection handled by this thread + */ + YuHW2HandlerThread(Socket socket) + { + this.socket = socket; + } + /** + * Program invocation and execution starts here - but is illegal and unwanted, so warn the unsuspecting user! + * @param args command-line arguments + */ + public static void main(String[] args) + { + System.out.println ("*** YuHW2HandlerThread is not a standalone executable progam."); + System.out.println ("*** Please run TcpExample4DispatchServer instead... now exiting."); + } + + /** Handles one connection. We add an artificial slowness + * to handling the connection with a sleep(). This means + * the client won't see a server connection response for ten seconds (default). + */ + // @overriding run() method in Java Thread class is deliberate + @Override + public void run() + { + try { + System.out.println(YuHW2HandlerThread.class.getName() + " starting to handle a thread..."); + + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + PrintStream ps = new PrintStream(socket.getOutputStream()); + + // Sequence of the Knock Knock joke + String clientMessage = in.readLine(); + System.out.println("Client: " + clientMessage); + + if ("Knock Knock".equals(clientMessage)) { + ps.println("Who's there?"); + ps.flush(); + } + + clientMessage = in.readLine(); + System.out.println("Client: " + clientMessage); + + if ("Hatch".equals(clientMessage)) { + ps.println("Hatch who?"); + ps.flush(); + } + + clientMessage = in.readLine(); + System.out.println("Client: " + clientMessage); + + if ("God Bless You!".equals(clientMessage)) { + System.out.println("Joke sequence complete."); + } + + socket.close(); // all clear, no longer need socket + System.out.println(YuHW2HandlerThread.class.getName() + " finished handling a thread, now exit."); + } catch(IOException e) { + System.out.println("Problem with " + YuHW2HandlerThread.class.getName() + " networking:"); + System.out.println("Error: " + e); + if (e instanceof java.net.BindException) { + System.out.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + } +} diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Server.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Server.java new file mode 100644 index 0000000000000000000000000000000000000000..9c2abe6e3842e71efa5e9e2bb9ee66d407392069 --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Yu/YuHW2Server.java @@ -0,0 +1,58 @@ +package TcpExamples; + +import java.io.IOException; +import java.net.*; + +/** + * @author Jin Hong Yu + */ +public class YuHW2Server +{ + /** Default constructor */ + public YuHW2Server() + { + // default constructor + } + /** + * Program invocation, execution starts here + * @param args command-line arguments + */ + public static void main(String[] args) + { + try { + ServerSocket serverSocket = new ServerSocket(2317); + Socket clientConnectionSocket; + TcpExample4HandlerThread handlerThread; + + int connectionCount = 0; // state variable + + System.out.println(TcpExample4DispatchServer.class.getName() + " ready to accept socket connections..."); + while (true) // infinite loop + { + clientConnectionSocket = serverSocket.accept(); // block! until connected + + connectionCount++; // unblocked, got another connection + + + System.out.println("============================================================="); + System.out.println(TcpExample4DispatchServer.class.getName() + ".handlerThread created for connection #" + connectionCount + "..."); + + // hand off this aready-created and connected socket to constructor + handlerThread = new TcpExample4HandlerThread(clientConnectionSocket); + handlerThread.start();// invokes the run() method in that object + System.out.println(TcpExample4DispatchServer.class.getName() + ".handlerThread is now dispatched and running, using most recent connection..."); + + // while(true) continue looping, serverSocket is still waiting for another customer client + } + } + catch (IOException e) { + System.out.println("Problem with " + TcpExample4DispatchServer.class.getName() + " networking:"); // describe what is happening + System.out.println("Error: " + e); + // Provide more helpful information to user if exception occurs due to running twice at one time + if (e instanceof java.net.BindException) { + System.out.println("*** Be sure to stop any other running instances of programs using this port!"); + } + } + System.out.println("============================================================="); // execution complete + } +}