package TcpExamples; import java.io.*; import java.net.*; /** * <p> * This utility class supports the {@link TcpExamples.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 TcpExamples.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 TcpExample4HandlerThread 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 */ TcpExample4HandlerThread(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 ("*** TcpExample4HandlerThread 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(TcpExample4HandlerThread.class.getName() + " starting to handle a thread..."); // get the connection output stream, then wait a period of time. OutputStream os = socket.getOutputStream(); PrintStream ps = new PrintStream(os); final long TIMEOUT = 2000; // 2000 milliseconds = 2 seconds, 10000 milliseconds = 10 seconds System.out.println(TcpExample4HandlerThread.class.getName() + " pausing for TIMEOUT=" + TIMEOUT + "ms" + " to emulate computation and avoid server-side overload"); Thread.sleep(TIMEOUT); // ps is the PrintStream is the Java way to use System.print() to pass data along the socket. ps.println("This message was written by the server " + TcpExample4HandlerThread.class.getName()); // TODO insert socket count here! ps.flush(); // make sure that it indeed escapes current process and reaches the client socket.close(); // all clear, no longer need socket System.out.println(TcpExample4HandlerThread.class.getName() + " finished handling a thread, now exit."); } catch(IOException | InterruptedException e) // either a networking or a threading problem { System.out.println("Problem with " + TcpExample4HandlerThread.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!"); } } }