package TcpExamples; import java.io.IOException; import java.net.*; /** * This server program works a bit differently by creating and dispatching a * new thread to handle multiple incoming socket connections, one after another, all running in parallel. * This advanced technique is often used in high=performance high=capacity server programs. * * @see TcpSentryClient * @see TcpSentryHandlerThread * @see TcpExample4Client * @see TcpExample4DispatchServer * @see TcpExample4HandlerThread * * @see <a href="../../../src/TcpExamples/TcpSentryTerminalLog.txt" target="blank">TcpSentryTerminalLog.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 TcpSentryDispatchServer { /** who is speaking, by role */ static String ACTOR = "[dispatcher] "; /** Default constructor */ public TcpSentryDispatchServer() { // 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 serverSocketConnection; TcpSentryHandlerThread sentryHandlerThread; int connectionCount = 0; // state variable System.out.println("==============================================================================="); System.out.println(ACTOR + "startup, menu 1g.TcpSentryServer, " + TcpSentryDispatchServer.class.getName()); while (true) // infinite loop, handling client connections and dispatching another handler thread { System.out.println(ACTOR + "waiting and ready to accept socket connection from a new client..."); serverSocketConnection = serverSocket.accept(); // block! until connected connectionCount++; // now unblocked, we have gotten another connection // TODO option for the student, provide initial message *to the client* // that we are handing off to a dispatch thread... because that is polite behavior. // Plenty of code in Example3, we instead let our proxy thread // TcpSentryHandlerThread introduce itself to the client. System.out.println(ACTOR + "received socket connection, creating handlerThread for visitor #" + connectionCount + "..."); // hand off this aready-created and connected socket to constructor sentryHandlerThread = new TcpSentryHandlerThread(serverSocketConnection); // creation logs a message sentryHandlerThread.start();// invokes the run() method in that object, which sends initial reply on the socket System.out.println(ACTOR + "a new sentry is now dispatched and running, using socket connection #" + connectionCount); System.out.println("==============================================================================="); // while(true) continue looping, serverSocket is still waiting for another customer client } } catch (IOException e) { System.out.println("*** " + ACTOR + "Problem with networking,"); // describe what is happening System.out.println(" " + 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.exit(-1); } finally { System.out.println(TcpSentryDispatchServer.class.getName() + " all done."); } System.out.println("==============================================================================="); // execution complete } }