From fe4cf86492ded2c005995743bfd072549842c361 Mon Sep 17 00:00:00 2001
From: brutzman <brutzman@nps.edu>
Date: Sun, 11 Aug 2024 16:07:21 -0700
Subject: [PATCH] ready for final checking

---
 .../TcpExamples/TcpSentryScenarioClient.java  | 100 +++++++++++-------
 .../TcpSentryScenarioDispatchServer.java      |  32 +++---
 .../TcpSentryScenarioHandlerThread.java       |  86 ++++++++++-----
 3 files changed, 133 insertions(+), 85 deletions(-)

diff --git a/examples/src/TcpExamples/TcpSentryScenarioClient.java b/examples/src/TcpExamples/TcpSentryScenarioClient.java
index 20f7fde618..4ec04abb2e 100644
--- a/examples/src/TcpExamples/TcpSentryScenarioClient.java
+++ b/examples/src/TcpExamples/TcpSentryScenarioClient.java
@@ -2,6 +2,7 @@ package TcpExamples;
 
 import static TcpExamples.TcpSentryScenarioHandlerThread.HALT_WHO_GOES_THERE;
 import static TcpExamples.TcpSentryScenarioHandlerThread.HOLD_IT_RIGHT_THERE;
+import static TcpExamples.TcpSentryScenarioHandlerThread.SENTRY_WATCH_PRESENT;
 import static TcpExamples.TcpSentryScenarioHandlerThread.YOU_MAY_PASS;
 import java.io.*;
 import java.net.*;
@@ -27,12 +28,12 @@ import java.net.*;
  */
 public class TcpSentryScenarioClient
 {
-    static String prefix = "[" + TcpSentryScenarioClient.class.getName() + "] ";
+    static String prefix = "[client] ";
     
     /** Default constructor */
     public TcpSentryScenarioClient()
     {
-        // default constructor
+        // no action needed here
     }
     static String DESTINATION_HOST = "localhost";
     static int    MAX_LOOP_COUNT   = 6;
@@ -42,12 +43,15 @@ public class TcpSentryScenarioClient
      * @param args command-line arguments
      */
     public static void main(String[] args) {
-        try {
-            System.out.println(prefix + " start, loop " + MAX_LOOP_COUNT + " times");
-            System.out.println("=======================================================");
+        try
+        {
+            System.out.println("===============================================================================");
+            System.out.println(prefix + "startup, menu 1h.TcpSentryClient, " + TcpSentryScenarioClient.class.getName());
+            System.out.println(prefix + "up to " + MAX_LOOP_COUNT + " visitors may approach.");
+            System.out.println("===============================================================================");
             for (int loopCount = 1; loopCount <= MAX_LOOP_COUNT; loopCount++) // loop then exit
             {
-                System.out.println(prefix + " creating new socket #" + loopCount + "...");
+                System.out.println(prefix + "creating client side to connect new socket #" + loopCount + "...");
 
                 // We request an IP to connect to ("localhost") and
                 // port number at that IP (2317). This establishes
@@ -60,59 +64,69 @@ public class TcpSentryScenarioClient
                 
 ////////////////////////////////////////////////////////////////////////////////////////////
 // Assignment code
-                String myName = new String();
+                String myName;
                 // input stream and output stream 
-                InputStream    inputStream       = socket.getInputStream();
-                Reader         inputStreamReader = new InputStreamReader(inputStream);
-                BufferedReader bufferedReader    = new BufferedReader(inputStreamReader);
+                InputStream    socketInputStream       = socket.getInputStream();
+                Reader         socketInputStreamReader = new InputStreamReader(socketInputStream);
+                BufferedReader socketBufferedReader    = new BufferedReader(socketInputStreamReader);
 
-                OutputStream outputStream = socket.getOutputStream();
-                PrintStream  printStream  = new PrintStream(outputStream);
-
-                String serverMessage = bufferedReader.readLine(); // blocks
-                System.out.println(prefix + ": message received from server='" + serverMessage + "'");
+                OutputStream   socketOutputStream = socket.getOutputStream();
+                PrintStream    socketPrintStream  = new PrintStream(socketOutputStream);
                 
-                String sentryResponse = bufferedReader.readLine();
-                System.out.println ("Sentry: " + sentryResponse);
-            
-                if (sentryResponse.equals(HALT_WHO_GOES_THERE))
+                while(true) // loop to handle query/response protocol
                 {
-                    // user provides name from console
-                    myName = System.console().readLine();
-                    printStream.println(myName); // send it back to dispatch server
-//                  System.out.println ("[trace] console return: " + myName);
-
-                    sentryResponse = bufferedReader.readLine();
-                    System.out.println ("Sentry: " + sentryResponse);
+                    String sentryQuery = socketBufferedReader.readLine(); // this line blocks
+                    System.out.println (sentryQuery);
+                    
+                    if (sentryQuery.endsWith(SENTRY_WATCH_PRESENT))
+                    {
+                         // duly noted, do not respond to this and continue looping/processing
+                         System.out.println (prefix + "(no response)");
+                    }
+                    else if (sentryQuery.contains("Hello"))
+                    {
+                         System.out.println (prefix + "Hello officer.");
+                    }
+                    else if (sentryQuery.endsWith(HALT_WHO_GOES_THERE))
+                    {
+                        System.out.println ("(visitors should type their name here)");
+                        // user provides name from console
+                        myName = System.console().readLine(); // this line blocks, awaiting keyboard input from user
+                        socketPrintStream.println(prefix + myName); // send it back to dispatch server
+    //                  System.out.println ("[trace] console return: " + myName);
 
-                    if      (sentryResponse.equals(YOU_MAY_PASS))
+                        if (myName.equalsIgnoreCase("quit") || myName.equalsIgnoreCase("exit"))
+                        {
+                            socketPrintStream.flush(); // ensure this final message goes through the socket
+                            System.out.println (prefix + "Exiting the program.");
+                            socket.close();
+                            System.exit(0);
+                        }
+                    }
+                    else if (sentryQuery.endsWith(YOU_MAY_PASS))
                     {
-                         System.out.println ("Thank you officer.");
+                         System.out.println (prefix + "Thank you officer.");
+                         break;
                     }
-                    else if (sentryResponse.equals(HOLD_IT_RIGHT_THERE))
+                    else if (sentryQuery.endsWith(HOLD_IT_RIGHT_THERE))
                     {
-                         System.out.println ("OK I am outta here!");
+                         System.out.println (prefix + "OK I am outta here!");
+                         break;
                     }
                     // handling unexpected cases is important
-                    else System.out.println ("I'm not sure what that means...");
+                    else System.out.println (prefix + "I'm not sure what that means, say again please...");
                 }
-
-                System.out.println("=======================================================");
+                System.out.println("===============================================================================");
                 // To push this further, launch multiple copies of TcpSentryScenarioClient simultaneously
-                
-                if (myName.equalsIgnoreCase("quit") || myName.equalsIgnoreCase("exit"))
-                {
-                    printStream.flush();
-                    socket.close();
-                }
             }
 
 ////////////////////////////////////////////////////////////////////////////////////////////
 
             System.out.println(prefix + " complete");
             // main method now exits
-        } catch (IOException e) {
-            System.out.println("*** Problem with " + prefix + "networking:"); // describe what is happening
+        }
+        catch (IOException e) {
+            System.out.println("*** " + prefix + "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) 
@@ -124,5 +138,9 @@ public class TcpSentryScenarioClient
                 System.out.println("*** Be sure to start the server before starting the client!");
             }
         }
+        finally
+        {
+            System.out.println("pau, all done");
+        }
     }
 }
diff --git a/examples/src/TcpExamples/TcpSentryScenarioDispatchServer.java b/examples/src/TcpExamples/TcpSentryScenarioDispatchServer.java
index fa03640ded..add710881e 100644
--- a/examples/src/TcpExamples/TcpSentryScenarioDispatchServer.java
+++ b/examples/src/TcpExamples/TcpSentryScenarioDispatchServer.java
@@ -24,7 +24,7 @@ import java.net.*;
  */
 public class TcpSentryScenarioDispatchServer
 {
-    static String prefix = "[" + TcpSentryScenarioDispatchServer.class.getName() + "] ";
+    static String prefix = "[dispatcher] ";
             
     /** Default constructor */
     public TcpSentryScenarioDispatchServer()
@@ -39,44 +39,46 @@ public class TcpSentryScenarioDispatchServer
     {
         try {
             ServerSocket                   serverSocket = new ServerSocket(2317);
-            Socket                         clientConnectionSocket;
-            TcpSentryScenarioHandlerThread handlerThread;
+            Socket                         serverSocketConnection;
+            TcpSentryScenarioHandlerThread sentryHandlerThread;
 
             int connectionCount = 0; // state variable
 
-            System.out.println(prefix + "waiting and ready to accept socket connection from client...");
+            System.out.println("===============================================================================");
+            System.out.println(prefix + "startup, menu 1g.TcpSentryServer, " + TcpSentryScenarioDispatchServer.class.getName());
             
             while (true) // infinite loop, handling client connections and dispatching another handler thread
             {
-                clientConnectionSocket = serverSocket.accept(); // block! until connected
+                System.out.println(prefix + "waiting and ready to accept socket connection from a new client...");
+                serverSocketConnection = serverSocket.accept(); // block! until connected
 
-                connectionCount++; // unblocked, got another connection
+                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
                 // TcpSentryScenarioHandlerThread introduce itself to the client.
                 
-                System.out.println("=============================================================");
-                System.out.println(prefix + ".handlerThread created for connection #" + connectionCount + "...");
+                System.out.println(prefix + "received socket connection, creating handlerThread for visitor #" + connectionCount + "...");
                 
                 // hand off this aready-created and connected socket to constructor
-                handlerThread = new TcpSentryScenarioHandlerThread(clientConnectionSocket); 
-                handlerThread.start();// invokes the run() method in that object
-                System.out.println(prefix + ".handlerThread is now dispatched and running, using most recent connection...");
+                sentryHandlerThread = new TcpSentryScenarioHandlerThread(serverSocketConnection); // creation logs a message
+                sentryHandlerThread.start();// invokes the run() method in that object, which sends initial reply on the socket
+                System.out.println(prefix + "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("Problem with " + prefix + " networking:"); // describe what is happening
-            System.out.println("Error: " + e);
+            System.out.println("*** " + prefix + "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) {
+            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);
         }
-        System.out.println("============================================================="); // execution complete
+        System.out.println("==============================================================================="); // execution complete
     }
 }
diff --git a/examples/src/TcpExamples/TcpSentryScenarioHandlerThread.java b/examples/src/TcpExamples/TcpSentryScenarioHandlerThread.java
index 37fe6051db..ea41a18761 100644
--- a/examples/src/TcpExamples/TcpSentryScenarioHandlerThread.java
+++ b/examples/src/TcpExamples/TcpSentryScenarioHandlerThread.java
@@ -33,17 +33,18 @@ import java.util.List;
  */
 public class TcpSentryScenarioHandlerThread extends Thread
 {
-    /** Sentry Scenario access list
+    /** Sentry Scenario access list, as written this list is case sensitive.
      * See {@linktourl https://stackoverflow.com/questions/1005073/initialization-of-an-arraylist-in-one-line }
      */
     public static List<String> allowedNamesList = 
-           Arrays.asList("Tim", "Stephen", "Mark", "Rene", "Simon", "James", "Ethan", "Jin Hong");
+           Arrays.asList("Tim", "Stephen", "Mark", "Rene", "Simon", "James", "Ethan", "Jin Hong", "Don");
     
-    public static final String HALT_WHO_GOES_THERE = "Halt who goes there?";
-    public static final String YOU_MAY_PASS        = "You may pass, have a great NPS MOVES day!";
-    public static final String HOLD_IT_RIGHT_THERE = "You may not pass, leave immediately or else";
+    public static final String SENTRY_WATCH_PRESENT = "Announcement: the sentry watch is present and standing guard.";
+    public static final String HALT_WHO_GOES_THERE  = "Halt who goes there?";
+    public static final String YOU_MAY_PASS         = "You may pass, have a great MOVES day!";
+    public static final String HOLD_IT_RIGHT_THERE  = "You may not pass! Leave immediately or else...";
     
-    private static final String prefix = "[" + TcpSentryScenarioHandlerThread.class.getName() + "] ";
+    private static final String prefix = "[sentry] ";
     
     /** The socket connection to a client */
     Socket socket;
@@ -57,6 +58,7 @@ public class TcpSentryScenarioHandlerThread extends Thread
     TcpSentryScenarioHandlerThread(Socket socket)
     {
         this.socket = socket;
+        System.out.println(prefix + "1h.TcpSentryClient, " + TcpSentryScenarioHandlerThread.class.getName());
     }
     /**
      * Program invocation and execution starts here - but is illegal and unwanted, so warn the unsuspecting user!
@@ -78,51 +80,77 @@ public class TcpSentryScenarioHandlerThread extends Thread
     {
         try
         {
-            System.out.println(prefix + "starting to handle a thread...");
+            System.out.println(prefix + "startup, menu 1g.TcpSentryServer, " + TcpSentryScenarioHandlerThread.class.getName());
+            // now starting to handle the thread
             
-            // input stream and output stream 
-            InputStream    inputStream       = socket.getInputStream();
-            Reader         inputStreamReader = new InputStreamReader(inputStream);
-            BufferedReader bufferedReader    = new BufferedReader(inputStreamReader);
+            // setup input stream and output stream 
+            InputStream    socketInputStream       = socket.getInputStream();
+            Reader         socketInputStreamReader = new InputStreamReader(socketInputStream);
+            BufferedReader socketBufferedReader    = new BufferedReader(socketInputStreamReader);
 
-            OutputStream outputStream = socket.getOutputStream();
-            PrintStream  printStream  = new PrintStream(outputStream);
+            OutputStream   socketOutputStream = socket.getOutputStream();
+            PrintStream    socketPrintStream  = new PrintStream(socketOutputStream);
             
             final long TIMEOUT = 100; // 2000 milliseconds = 2 seconds, 10000 milliseconds = 10 seconds
 //            System.out.println(prefix + " 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.
-            printStream.println(prefix + "This message was written by the server "); // TODO insert socket count here!
-            printStream.flush();     // make sure that it indeed escapes current process and reaches the client
             
 ////////////////////////////////////////////////////////////////////////////////////////////
 // Assignment code
+
+            // since this thread is running, a socket connection has already been received from dispatch server.
+            // PrintStream is the Java way to use System.print() to pass string data along the socket.
+            socketPrintStream.println(prefix + SENTRY_WATCH_PRESENT); 
+             System.out.println(prefix + SENTRY_WATCH_PRESENT);
+            // make sure that message indeed escapes current process and is pushed through socket to reach the client
+            socketPrintStream.flush();     
             
-            printStream.println(HALT_WHO_GOES_THERE);
-            System.out.println ("socket send:   " + HALT_WHO_GOES_THERE);
+            // now the query-response interactions begin...
+            socketPrintStream.println(prefix + HALT_WHO_GOES_THERE);
+             System.out.println(prefix + HALT_WHO_GOES_THERE);
             
-            String clientResponse = bufferedReader.readLine();
-            System.out.println ("clientResponse: " + clientResponse);
+            String clientResponse = socketBufferedReader.readLine();
+            System.out.println (clientResponse);
+            // trim prefix if neccessary
+            int messageIndex = clientResponse.indexOf("]");
+            if (messageIndex > 0)
+                clientResponse = clientResponse.substring(messageIndex + 1).trim();
             
-            if (clientResponse.equalsIgnoreCase("quit") || clientResponse.equalsIgnoreCase("exit"))
+            if (clientResponse.trim().equalsIgnoreCase("quit") || 
+                clientResponse.trim().equalsIgnoreCase("exit"))
             {
-                printStream.flush();
+                System.out.println (prefix + "Exiting the program.");
                 socket.close();
+                System.exit(0); // shuts down thread, not dispatch server
+            }
+            // simple response
+            socketPrintStream.println(prefix + "Hello, " + clientResponse);
+                   System.out.println(prefix + "Hello, " + clientResponse);
+
+            // now check credential and respond accordingly
+            if (allowedNamesList.contains(clientResponse))
+            {
+                socketPrintStream.println(prefix + YOU_MAY_PASS);
+                       System.out.println(prefix + YOU_MAY_PASS);
+            }
+            else
+            {
+                socketPrintStream.println(prefix + HOLD_IT_RIGHT_THERE);
+                       System.out.println(prefix + HOLD_IT_RIGHT_THERE);
             }
-            System.out.println ("Hello, " + clientResponse);
             
 ////////////////////////////////////////////////////////////////////////////////////////////
             
-////            socket.close(); // all clear, no longer need socket
-            System.out.println(prefix + "finished handling a thread, now exit.");
-            System.out.println("============================================================="); // execution complete
+//          socket.close(); // all clear, no longer need socket
+            System.out.println(prefix + "this visitor interaction is complete.");
+            System.out.println("=================================================================================");
+            // execution complete
         }
         catch(IOException | InterruptedException e) // either a networking or a threading problem
         {
-            System.out.println("Problem with " + prefix + " networking:"); // describe what is happening
-            System.out.println("Error: " + e);
+            System.out.println("*** " + prefix + "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)
-- 
GitLab