From e8c1a1cceddc9f8ad09b7fa229d1e0e65ecdaf6a Mon Sep 17 00:00:00 2001
From: ethanjwilliams <ethanjwilliams@localhost>
Date: Tue, 30 Jul 2024 14:22:04 -0700
Subject: [PATCH] Williams - Homework 2

---
 .../homework2/Williams/HW2Client.java         | 120 ++++++++++++------
 .../homework2/Williams/HW2Server.java         |  80 ++++++------
 .../homework2/Williams/HW2Thread.java         |  97 ++++++++++++++
 3 files changed, 218 insertions(+), 79 deletions(-)
 create mode 100644 assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Thread.java

diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Client.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Client.java
index aefe2b2e3a..d9840cc2a1 100644
--- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Client.java
+++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Client.java
@@ -1,9 +1,12 @@
 package MV3500Cohort2024JulySeptember.homework2.Williams;
 
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.util.Scanner;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.Socket;
 
 /**
  * Client file for HW2.
@@ -13,45 +16,84 @@ import java.util.Scanner;
 public class HW2Client {
 
     /**
-     * @param args the command line arguments
+     * Default constructor
+     */
+    public HW2Client() {
+
+    }
+
+    static String DESTINATION_HOST = "localhost";
+    static int DESTINATION_PORT = 2317;
+    static int MAX_LOOP_COUNT = 1;
+
+    /**
+     * @param args command-line arguments
      */
     public static void main(String[] args) {
-        DatagramSocket socket = null;
-        Scanner scanner = new Scanner(System.in);
-        try {
-            socket = new DatagramSocket();
-            InetAddress serverAddress = InetAddress.getByName("localhost");
-            byte[] sendData = new byte[1024];
-            byte[] receiveData = new byte[1024];
-
-            System.out.print("Can you solve my riddle??\n");
-            System.out.print("Try to solve the riddle: I speak without a mouth and hear without ears. I have no body, but I come alive with wind. What am I?\n");
-            while (true) {
-                System.out.print("Enter your answer: ");
-                String answer = scanner.nextLine();
-                sendData = answer.getBytes();
-
-                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddress, 9876);
-                socket.send(sendPacket);
-
-                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
-                socket.receive(receivePacket);
-                String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
-                System.out.println("Server Said: " + response);
-
-                if (response.startsWith("Good")) {
-                    break;
+        if (args.length > 0) {
+            DESTINATION_HOST = args[0];
+        }
+        if (args.length > 1) {
+            DESTINATION_PORT = Integer.parseInt(args[1]);
+        }
+        if (args.length > 2) {
+            MAX_LOOP_COUNT = Integer.parseInt(args[2]);
+        }
+
+        System.out.println("=======================================================");
+
+        for (int loopCount = 1; loopCount <= MAX_LOOP_COUNT; loopCount++) {
+            System.out.println(HW2Client.class.getName() + " creating new socket:");
+
+            long startTime = System.currentTimeMillis();
+            Socket socket = null;
+            BufferedReader br = null;
+            PrintWriter pw = null;
+
+            try {
+                socket = new Socket(DESTINATION_HOST, DESTINATION_PORT);
+                InputStream is = socket.getInputStream();
+                br = new BufferedReader(new InputStreamReader(is));
+                OutputStream os = socket.getOutputStream();
+                pw = new PrintWriter(os, true);
+
+                String serverMessage = br.readLine();
+                System.out.println("Server: " + serverMessage);
+
+                String clientResponse = "Ethan";
+                pw.println(clientResponse);
+                System.out.println("Client: " + clientResponse);
+
+                String serverFinalResponse = br.readLine();
+                long readTime = System.currentTimeMillis();
+                long timeLength = readTime - startTime;
+
+                System.out.println("Server response: " + serverFinalResponse);
+                System.out.println(HW2Client.class.getName() + ": time msec required for read = " + timeLength);
+                System.out.println("=======================================================");
+
+            } catch (IOException e) {
+                System.out.println("Problem with " + HW2Client.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!");
+                }
+            } finally {
+                try {
+                    if (br != null) {
+                        br.close();
+                    }
+                    if (pw != null) {
+                        pw.close();
+                    }
+                    if (socket != null && !socket.isClosed()) {
+                        socket.close();
+                    }
+                } catch (IOException e) {
+                    System.out.println("Error closing resources: " + e);
                 }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-            if (socket != null && !socket.isClosed()) {
-                socket.close();
             }
         }
+        System.out.println(HW2Client.class.getName() + " complete");
     }
 }
diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Server.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Server.java
index 7a7d2df72b..d77c20822f 100644
--- a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Server.java
+++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Server.java
@@ -1,8 +1,9 @@
 package MV3500Cohort2024JulySeptember.homework2.Williams;
 
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
 
 /**
  * Server file for HW2.
@@ -12,50 +13,49 @@ import java.net.InetAddress;
 public class HW2Server {
 
     /**
-     * @param args the command line arguments
+     * Default constructor
      */
-    public static void main(String[] args) {
-        DatagramSocket socket = null;
-        String riddleAnswer = "echo";
+    public HW2Server() {
+
+    }
 
+    /**
+     * @param args command-line arguments
+     */
+    public static void main(String[] args) {
         try {
-            socket = new DatagramSocket(9876);
-            byte[] receiveData = new byte[1024];
-            byte[] sendData = new byte[1024];
-            int count = 1;
-            System.out.println("Server has started, waiting for client...");
-
-            boolean isRunning = true;
-            while (isRunning) {
-                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
-                socket.receive(receivePacket);
-
-                String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
-                InetAddress clientAddress = receivePacket.getAddress();
-                int clientPort = receivePacket.getPort();
-
-                System.out.println("Client sent: " + message);
-
-                String response;
-                if (message.trim().equalsIgnoreCase(riddleAnswer)) {
-                    response = "Good Job!! You solved the riddle in " + count + " tries!";
-                    isRunning = false;
-                } else {
-                    response = "Wrong answer. Try again!";
-                    count++;
-                }
+            ServerSocket serverSocket = new ServerSocket(2317);
+            HW2Thread handlerThread;
+            Socket clientConnection;
+
+            int connectionCount = 0;
+
+            System.out.println(HW2Server.class.getName() + " ready to accept socket connections...");
+            while (true) {
+                clientConnection = serverSocket.accept();
 
-                sendData = response.getBytes();
-                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);
-                socket.send(sendPacket);
+                connectionCount++;
+
+                try {
+                    PrintWriter out = new PrintWriter(clientConnection.getOutputStream(), true);
+                    out.println("I'd like to shake your hand. What's your name?");
+                } catch (IOException e) {
+                    System.out.println("Error sending initial message to client: " + e);
+                }
 
+                System.out.println("=============================================================");
+                System.out.println(HW2Server.class.getName() + ".handlerThread created for connection #" + connectionCount + "...");
+                handlerThread = new HW2Thread(clientConnection);
+                handlerThread.start();
+                System.out.println(HW2Server.class.getName() + ".handlerThread is now dispatched and running, using most recent connection...");
             }
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            if (socket != null && !socket.isClosed()) {
-                socket.close();
+        } catch (IOException e) {
+            System.out.println("Problem with " + HW2Server.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!");
             }
         }
+        System.out.println("=============================================================");
     }
 }
diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Thread.java b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Thread.java
new file mode 100644
index 0000000000..de3838eba5
--- /dev/null
+++ b/assignments/src/MV3500Cohort2024JulySeptember/homework2/Williams/HW2Thread.java
@@ -0,0 +1,97 @@
+package MV3500Cohort2024JulySeptember.homework2.Williams;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.Socket;
+
+/**
+ *
+ * @author ethanjwilliams
+ */
+public class HW2Thread extends Thread {
+
+    /**
+     * The socket connection to a client
+     */
+    private final Socket socket;
+    private static int connectionCount = 0;
+
+    /**
+     * 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
+     */
+    HW2Thread(Socket socket) {
+        this.socket = socket;
+        synchronized (HW2Thread.class) {
+            connectionCount++;
+        }
+    }
+
+    /**
+     * 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("*** HW2Thread is not a standalone executable progam.");
+        System.out.println("*** Please run HW2Server 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).
+     */
+    @Override
+    public void run() {
+        BufferedReader br = null;
+        PrintStream ps = null;
+        try {
+            System.out.println(HW2Thread.class.getName() + " starting to handle a thread...");
+
+            InputStream is = socket.getInputStream();
+            br = new BufferedReader(new InputStreamReader(is));
+            OutputStream os = socket.getOutputStream();
+            ps = new PrintStream(os);
+
+            String clientResponse = br.readLine();
+            System.out.println("Received from client: " + clientResponse);
+
+            if ("Ethan".equalsIgnoreCase(clientResponse.trim())) {
+                ps.println("Nice to meet you!");
+            } else {
+                ps.println("Say your name again.");
+            }
+            ps.flush();
+
+            System.out.println(HW2Thread.class.getName() + " finished handling a thread, now exit.");
+        } catch (IOException e) {
+            System.out.println("Problem with " + HW2Thread.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!");
+            }
+        } finally {
+            try {
+                if (br != null) {
+                    br.close();
+                }
+                if (ps != null) {
+                    ps.close();
+                }
+                socket.close();
+            } catch (IOException e) {
+                System.out.println("Error closing resources: " + e);
+            }
+        }
+    }
+}
-- 
GitLab