Benaiah\’s Computer Experiences

November 26, 2009

Exceptional Code Comments

Filed under: Uncategorized — Tags: — Benaiah @ 11:41 pm

The code below is not exceptional in itself…however, the comments that were provided by a friend are extremely exceptional and well worth the read!

/**********************************************************
 * Student Name: Benaiah Henry
 * Course: COSC 4303
 * Package: Server
 * File name: ConnectionHandler.java
 *
 * Purpose:
 *
 * Development Computer: Dell Dimenstion E520
 * Operating System: Ubuntu 9.10
 * Integrated Development Environment (IDE): Netbeans IDE 6.7.1
 * Compiler: javac
 **************************************************************/
import java.net.*;
import java.io.*;
import java.util.*;

/**
 * This handles the connection (not MANAGE, HANDLE) Management is an entirely
 * different class which probably involves lots of pointy ears, walking around,
 * and looking for the token ring under the desk (it's very small and hard to
 * find). But that's not this class.
 *
 * This class is more like Dogbert. It smacks you upside the head, tells you
 * things you need to know but won't listen to, and walks away with the money.
 * That's what happens when we throw an exception here - Dogbert takes the money.
 * @author Benaiah Henry
 */
public class ConnectionHandler {

   ServerSocket serverSocket;
   ResultHandler resultHandler;
   String serverIP;
   ArrayList<ConnectedUser> connectedUsers;
   //ArrayList<ServerSocket> serverSockets;
   public static final int DEFAULT_PORT = 1234;
   public static final int MAX_CLIENTS = 500;
   public static final int ACCEPT_TIMEOUT_LENGTH = 10;
   public static final int SHORT_STRING = 32;

   /**
    *
    * @throws java.io.IOException
    */
   public ConnectionHandler(ResultHandler resultH) {
      resultHandler = resultH;
      try {
         connectedUsers = new ArrayList<ConnectedUser>();
         //serverSockets = new ArrayList<ServerSocket>();

         InetAddress localIP = InetAddress.getLocalHost();
         serverIP = localIP.getHostAddress();

         serverSocket = new ServerSocket(DEFAULT_PORT, MAX_CLIENTS);

         serverSocket.setSoTimeout(5);

      } catch (IOException e) {
         System.err.println("Failed to create ServerSocket");
      } // End Try/Catch
   } // End Constructor

   /*
    * Have you ever been bothered by how none of the clocks anywhere agree
    * with each other? Have you ever just wanted a short little method
    * that would synchronize everything? That would just update and make
    * standardized time work? Yes we can!
    * But this is not that method...
    */

   //**************************************************************/
   /**
	* Checks for new data from all clients
	*/
   public void update() {
      ConnectedUser temp = null;

      for (int i = 0; i < connectedUsers.size(); i++) {
         temp = connectedUsers.get(i);
         readFromClient(temp.getSocket(), temp.getDataInputStream(), temp.getDataOutputStream(), i);
      } // End for

   } // End update

   //**************************************************************/
   /**
	* Checks a serverSocket for new client connections
	* And Asks accounting department to cut check to our wonderful clients
	*
	*/
   public void checkForClients() {
      DataOutputStream out;
      DataInputStream in;
      Socket connection;
      InetAddress tempIP;
      String IP;

      try {

         connection = serverSocket.accept();
         //connection.getChannel().configureBlocking(false);

         //System.err.println("after connection made");

         in = new DataInputStream(connection.getInputStream());
         out = new DataOutputStream(connection.getOutputStream());
         tempIP = connection.getInetAddress();
         IP = tempIP.toString();

         //System.err.println("after ip string");

         // create a new user ex nihilo
         connectedUsers.add(new ConnectedUser(IP, null, connection, in, out));

      //System.err.println("after add user");
      } catch (SocketTimeoutException e) {
         System.err.println("accept timeout - continuing execution");
      } catch (IOException e) {
         System.err.println("socket accept failed");
      } // End Try/Catch
   } // End checkForClients

   //**************************************************************/
   /**
    *
    * @param connection The socket to read from
    * @param in	The DataInputStream of the connection
    * @param out The DataOutputStream of the connection
    * @param index Index of the client to read from
    */
   public void readFromClient(Socket connection, DataInputStream in, DataOutputStream out, int index) {
      int msgTypeID;

      try {
         connection.setSoTimeout(5);
         msgTypeID = in.readInt();

         switch (msgTypeID) {
            case 100:
               process100(in, index);
               break;
            case 300:
               process300(in, index);
               break;
            case 900:
               process900(index, connection, in, out);
               break;
            default:
               System.err.println("Invalid message code");
               break;
         } // End switch
      } catch (IOException e) {
         System.err.println("No data from client");
      } // End Try/Catch
   }// End readFromClient

   /**
    * The wonderful processing method
    * @param in A DataInputStream
    * @param index Index of client
    */
   private void process100(DataInputStream in, int index) {
      String alias = null;
      byte[] temp = new byte[SHORT_STRING];

      try {
         for (int i = 0; i < SHORT_STRING; i++) {
            temp[i] = in.readByte();
         }
         alias = new String(temp).trim();
         connectedUsers.get(index).setAlias(alias);
         System.out.println(alias);
      } catch (IOException e) {
         System.err.println("Failed to process 100 message");
      }
   }

   /**
    * The other wonderful processing method, but 3 times better than the first one
    * @param in A DataInputStream
    * @param index Client index
    */
   private void process300(DataInputStream in, int index) {
      int questionNum = 0;
      boolean didAnswer = false;	    // yes, I know this is bad grammar
      int timeTaken = 0;	      	    // careful, there will be problems if the user takes longer than 49,710 days to answer
					    // if you think that's too long, consider using 'long'
      String answer = null;
      byte[] temp = new byte[SHORT_STRING];

      try {
         questionNum = in.readInt();
         didAnswer = in.readBoolean();
         timeTaken = in.readInt();
         for (int i = 0; i < SHORT_STRING; i++) {
            temp[i] = in.readByte();
         } // End for
         answer = new String(temp).trim();
      } catch (Exception e) {
         System.err.println("Failed to process 300 message");
      } // End Try/catch

      resultHandler.storeAnswer(questionNum, didAnswer, timeTaken, answer, connectedUsers.get(index).getIPAddress());
   } // End process300

   /*
    * Some of you may be wondering why process900 sends 999. Let me explain:
    * Process 0 was created.
    * process 0 begot process 100. Process 0 lived for
    * 425 seconds and had other sons and daughters.
    * Process 100 begot process 200. Process 100 lived for
    * 511 seconds and had other sons and daughters.
    * Process 200 begot process 300. Process 200 lived for
    * 441 seconds and had other sons and daughters.
    * Process 300 begot process 400. Process 300 lived for
    * 225 seconds and had other sons and daughters.
    * Process 400 begot process 500. Process 500 lived for
    * 311 seconds and had other sons and daughters.
    * Process 500 begot process 600. Now process 500 lived in the days of
    * Windows ME. Dark were the times, and wild ran the memory manager.
    * Process 500 lived 23 seconds and had no other children. Then it seg-faulted.
    * Process 600 begot process 700. Process 600 lived for
    * 259 seconds and had other sons and daughters.
    * Process 700 begot process 800, who was lost in the upgrade to Vista.
    * Process 700 begot process 900 (after confirming "allow" 71942 times.
    * Children can be quite a security risk). Process 700 lived for
    * 111 seconds and had other sons and daughters.
    *
    * Now process 900 walked with the kernel, and had many sons
    * and daughters. It was granted a large memory footprint, and the
    * exclusive use of 2 CPU cores, plus direct access to the PCI bus.
    * Having so much wealth to manage, Process 900 diligently instructed
    * his children, giving to some 10mb, to other 100mb, and to some whole
    * gigabytes of memory. Thus was process 999, son of process 900,
    * alloted communication with the first 13 pins of the card in 2nd PCI
    * slot (which happens to be the NIC), and is thus responsible for
    * for sending poetry, free chicken sandwich coupons, and instructions
    * on building to-scale parking garages on the kitchen table without
    * creating multi-car pileups.
    */

   //**************************************************************/
   /**
	*
	* Closes the connections
	* @param index Index of client to close connections for
	* @param connection The socket of the client
	* @param in DataInputStream of connection
	* @param out DataOutputStream of connection
	*/
   private void process900(int index, Socket connection, DataInputStream in, DataOutputStream out) {
      send999(connectedUsers.get(index).getAlias(), out);

      try {
         in.close();
         out.close();
         connection.close();
      } catch (Exception e) {
         System.err.printf("Failed to close connection for client at IP address: %s", connection.getInetAddress().toString());
      } // End Try/Catch
   } // End process900

   //**************************************************************/
   /**
	* Send Connection has been closed
	* @param alias Username of client
	* @param out DataOutputStream of client
	*/
   private void send999(String alias, DataOutputStream out) {
      try {
         out.writeInt(999);
         writeString(alias, SHORT_STRING, out);
      } catch (IOException e) {
         System.err.println("Failed to send 999 message");
      } // End Try/Catch
   } // End send999

   /**
	* Writes strings to a DataOutputStream.  Either truncates at size, or pads with 0's to size.
	*
    * Cutting a string would be more fun, but such is life
	*
    * @param s
    * @param size
    * @param out
    */
   private void writeString(String s, int size, DataOutputStream out) {
      try {
         if (s.length() < (size - 1)) {
            out.writeBytes(s);

            for (int i = 0; i < (size - s.length()); i++) {
               out.writeByte(0);
            } // End for
         } else if (s.length() > (size - 1)) {
            s = s.trim().substring(0, (size - 1));
            out.writeBytes(s);
            out.writeByte(0);
         } else {
            out.writeBytes(s);
            out.writeByte(0);
         } // End if/else if/else
      } catch (IOException e) {
         System.err.println("Write failed");
         System.exit(-1);
      } // End Try/Catch
   } // End writeString

   //**************************************************************/
   /**
	* Send the question to all clients
	* @param questionNum Number of the question
	* @param questionType Type of question as an int
	* @param timeLimit Time limit on question
	* @param tallyMode Force tally mode
	* @param optionCount Number of answer options
	* @param questionText The question
	* @param answerOptions All answer options concatenated and separated by ascii "04"
	*/
   public void sendQuestion(int questionNum, int questionType, int timeLimit, boolean tallyMode, int optionCount, String questionText, String answerOptions) {
      ConnectedUser temp = null;
      DataOutputStream out;

      try {
         for (int i = 0; i < connectedUsers.size(); i++) {
            temp = connectedUsers.get(i);
            out = temp.getDataOutputStream();

            out.writeInt(200);
            out.writeInt(questionNum);
            out.writeInt(questionType);
            out.writeInt(timeLimit);
            out.writeBoolean(tallyMode);
            out.writeInt(optionCount);
            writeString(questionText, 256, out);
            writeString(answerOptions, 256, out);
         } // End for
      } catch (IOException e) {
         System.err.printf("Failed to send 200 message to IP address %s", temp.getSocket().getInetAddress().toString());
      } // End Try/Catch
   } // End SendQuestion

   //The llama in the sky has recieved your request
   //but your question is judged as causing unrest
   //the words are malicious
   //puncuation sadicious
   //we'll have to correct for success

   //**************************************************************/
   /**
	* Send the correct answer to clients
	* @param isCorrect Whether the answer was correct
	* @param timeTaken How long it took to answer
	* @param submittedAnswer Client's submitted answer
	* @param correctAnswer Correct answer
	*/
   public void sendGradedQuestion(boolean isCorrect, int timeTaken, String submittedAnswer, String correctAnswer) {
      ConnectedUser temp = null;
      DataOutputStream out;

      try {
         for (int i = 0; i < connectedUsers.size(); i++) {
            temp = connectedUsers.get(i);
            out = temp.getDataOutputStream(); //check for actual function name

            //we sent a 400 (I don't know why)
            //I would have chosen 3,4, or pi
            //but no one asked me
            //or revealed the design
            //no diagrams, no tree
            //(they charged a $10 fine)
            out.writeInt(400);
            out.writeBoolean(isCorrect);
            out.writeInt(timeTaken);
            writeString(submittedAnswer, 32, out);
            writeString(correctAnswer, 32, out);
         } // End for
      } catch (IOException e) {
         System.err.println("Failed to send 400 message to all clients");
      } // End Try/Catch
   }// End sendGradedQuestion

   //**************************************************************/
   /**
	* Send notification of end of set to all clients
	*/
   public void sendEndOfSet() {
      ConnectedUser temp = null;
      DataOutputStream out;

      try {
         for (int i = 0; i < connectedUsers.size(); i++) {
            temp = connectedUsers.get(i);
            out = temp.getDataOutputStream();

            out.writeInt(500);
         } // End for
      } catch (IOException e) {
         System.err.println("Failed to send 500 message to all clients");
      } // End Try/Catch
   }// End sendEndOfSet

   //**************************************************************/

   public String getServerIP() {

      return serverIP;
   } // End getServerIP

   //**************************************************************/

   public int getConnectedUserCount() {

      return connectedUsers.size();
   } // End getConnectedUserCount
}// End ConnectionHandler

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/**********************************************************
 * Student name: Benaiah Henry
 * Course: COSC 4303
 * Package: Client
 * File name: ConnectionManager.java
 *
 * Purpose: Handles reading and writing to the network.
 *			Also passes information to controller to be give
 *		    to the UI.
 *
 * Development Computer: Dell Dimenstion E520
 * Operating System: Ubuntu 9.04
 * Integrated Development Environment (IDE): Netbeans IDE 6.7.1
 * Compiler: javac
//**************************************************************/
import java.net.*;
import java.io.*;
import java.util.*;

/**
 * Handles network connection between client and server
 *
 * In the beginning was the connection. And the connection was with packets, but
 * the connection was without packets. It was without packets in the beginning.
 * Thus, we created this manager.
 *
 * @author Benaiah Henry
 * @version e/pi
 */
public class ConnectionManager {

   Socket clientSocket;
   DataOutputStream out;
   DataInputStream in;
   BufferedReader inString;
   Controller controller;
   public static final int MAX = 32;
   public static final int SHORT_STRING = 32;
   public static final int LONG_STRING = 256;

   /**
    *
    * @param controllerRef  Reference to Controller
    */
   public ConnectionManager(Controller controllerRef) {
      controller = controllerRef;
   } // End constructor

   //**************************************************************/
   /**
    * Connect to the Clickermatic server
    * @param address IP Address of server
    * @param port Port on server
    * @param alias Username
    */
   public void logIn(String address, int port, String alias) {
      try {
         clientSocket = new Socket(address, port);
         in = new DataInputStream(clientSocket.getInputStream());
         inString = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
         out = new DataOutputStream(clientSocket.getOutputStream());
      } catch (IOException e) {
         System.err.println("Connection Failed");
         System.exit(-1);
      } // End Try/Catch

      //thus spake the Grand Llama. And the earth was silent as the grand
      //message broke forth upon the ocean of packets and soughdough bread (for
      //the internet has been filled, since the beginning with bakery goodness).

      sendHello(alias);
   } // End logIn

   //**************************************************************/
   /**
    * Send HELLO (100) packet
    * @param alias Username   ***Can we make it amphibious???
    */
   private void sendHello(String alias) {
      try {
         out.writeInt(100);
         writeString(alias, SHORT_STRING);
      } catch (IOException e) {
         System.err.println("Failed to send HELLO");
         System.exit(-1);
      } // End Try/Catch
   } // End sendHello

   //**************************************************************/
   /**
    * Send user answer to server
    * @param questionNumber
    * @param answeredInTimeLimit
    * @param elapsedTime
    * @param clientAnswer
    */
   public void submitAnswer(int questionNumber, boolean answeredInTimeLimit,
           int elapsedTime, String clientAnswer) {
      try {
         out.writeInt(300);
         out.writeInt(questionNumber);
         out.writeBoolean(answeredInTimeLimit);
         out.writeInt(elapsedTime);
         writeString(clientAnswer, SHORT_STRING);
      } catch (IOException e) {
         //alas!! The soughdough bread hath clogged the message! Retreat, and
         //contemplate the freshness of your bread.
         System.err.println("Failed to send 300 message");
         //System.exit(-1);
      } // End Try/Catch
   } // End submitAnswer

   //**************************************************************/
   /**
    * Read packet in from server, check msgTypeID and call correct process method.
    */
   public void readFromServer() {
      int msgTypeID;
      try {
         msgTypeID = in.readInt();

         switch (msgTypeID) {
            case 200:
               process200();
               break;
            case 400:
               process400();
               break;
            case 500:
               process500();
               break;
            case 999:
               process999();
               break;
            default:
               System.err.println("Invalid message code");
               break;
         } // End switch
      } catch (IOException e) {
         System.err.println("Failed to read from server");
      } // End Try/Catch
   } // End readFromServer

   /*
    * Ah, the 200 process! Mightiest of all! How swift and majestic its
    * response! Gaze upon the internet and tell me, Muse, is there any greater
    * response than this? How gloriously bright are its 0s. How regal the
    * leading 2! This, the response that launched a thousand ships to the
    * harbors of Troy - tell me, Muse, of that story...
    */
   //**************************************************************/
   /**
    * Recieve question from server and pass to controller.
    */
   private void process200() {

      //the question of no
      //does not start with an 'o'
      //though it's type be int
      //it shall not repent
      //and begin with zero
      //(an unworthy foe)

      int questionNo = 0;
      int questionType = 0;
      int timeLimit = 0;

      //We stand united against tallying! Viva la revolution!
      boolean tallyMode = false;
      String questionText = null;
      int optionCount = 0;
      String answerOptions = null;
      byte[] temp = new byte[LONG_STRING];
      ArrayList<String> answerOptionsList = null;

      try {
         questionNo = in.readInt();
         questionType = in.readInt();
         timeLimit = in.readInt();
         tallyMode = in.readBoolean();
         for (int i = 0; i < LONG_STRING; i++) {
            temp[i] = in.readByte();
         } // End for
         questionText = new String(temp).trim();
         System.out.print(questionText);
         optionCount = in.readInt();
         for (int i = 0; i < LONG_STRING; i++) {
            temp[i] = in.readByte();
         } // End for
         answerOptions = new String(temp).trim();
         //System.out.print(answerOptions);
         answerOptionsList = separateAnswers(answerOptions, optionCount);

      } catch (IOException e) {
         //thus passes the glory of the world...
         System.err.println("Failed to process 200 message");
      } // End Try/Catch

      /**
       * @see Controller
       */
      controller.submitQuestionToUI(questionNo, questionType, timeLimit,
              tallyMode, questionText, answerOptionsList);
   } // End process200

   //**************************************************************/
   //mysterious murky
   //succesful data suicide
   //unfortunate depressing heart-wrenching callamitive
   //failure
   /**
    * Recieve question answer from server and pass to controller
    */
   private void process400() {
      String submittedAnswer = null;
      String correctAnswer = null;
      boolean isRightAnswer = false;
      int timeTaken = 0;
      byte[] temp = new byte[LONG_STRING];

      try {
         isRightAnswer = in.readBoolean();
         timeTaken = in.readInt();
         for (int i = 0; i < LONG_STRING; i++) {
            temp[i] = in.readByte();
         } // End for
         submittedAnswer = new String(temp).trim();
         for (int i = 0; i < LONG_STRING; i++) {
            temp[i] = in.readByte();
         } // End for
         correctAnswer = new String(temp);

      } catch (IOException e) {
         System.err.println("Failed to process 400 message");
        // System.exit(-1);
      } // End Try/Catch

      /**
       * @see Controller
       */
      controller.submitAnswerToUI(submittedAnswer, correctAnswer, isRightAnswer,
              timeTaken);
   } // End process400

   /*
    * You be server errored! Errors upon you! Bwuahahaha!!!
    */
   //**************************************************************/
   /**
    * Send notification of end of question set to controller
    */
   private void process500() {
      controller.endOfSet();
   } // End process500

   //**************************************************************/
   /*
    * We're sorry: The pipe seems to be clogged with sheep. If this is the first
    * time you are experiencing this problem, please wait a minute and try
    * again. If this is a recurring error, please contact 1-800-BAH-NOSHEEP.
    */
   /**
    * Close read/write streams and socket.
    */
   private void process999() {
      try {

         out.close();
         in.close();
         inString.close();
         clientSocket.close();
         controller.disconnectReceived();
      } catch (IOException E) {
         System.err.println("Failed to close connection");
        // System.exit(-1);
      } // End Try/Catch
   } // End process 999

   //**************************************************************/
   /**
    * Write a string to a packet.
    * Ensures that <code>s</code> is exactly <code>size</code>.
    * <code> s.length > size</code>, truncate
    * <code> s.length < size</code>, pad to <code>size</code> with 0's
    * @param s String to send
    * @param size Desired length of string
    */
   private void writeString(String s, int size) {
      try {
         if (s.length() < (size - 1)) {
            out.writeBytes(s);

            for (int i = 0; i < (size - s.length()); i++) {
               out.writeByte(0);
            } // End for
         } else if (s.length() > (size - 1)) {
            s = s.trim().substring(0, (size - 1));
            out.writeBytes(s);
            out.writeByte(0);
         } else {
            out.writeBytes(s);
            out.writeByte(0);
         } //End if/else if/else
      } catch (IOException e) {
         //ah, but read succeed!
         System.err.println("Write failed");
        // System.exit(-1);
      } // End Try/Catch
   } // End writeString

   /*
    * We thought about combining the answers, but it went something like this:
    * Scenario 1:
    * Joe Cool: Question?
    * Random teenager: Answer!!
    * Joe Cool: yay! that made sense!
    * Random teenager: Answer part 2!!
    * Joe Cool: Wait, what? You already answered!
    * Random teenager: Answer part 3!!
    * Joe Cool: Hey - that contradicted!
    * Random teenager: Extremely long and confusing answer part 4!!
    * Joe Cool: (forgetting parts 1,2, and 3) oh, that makes sense!
    *
    * Scenario 2:
    * Joe Cool: Question?
    * Random teenager: Answer parts 1,2,3, and extremely long and confusing
    *					answer part 4!!!
    * Joe Cool: (brain explodes)
    *
    * So you see, seperate answers avoid exploading heads. RAs hate those.
    */
   //**************************************************************/
   /**
    * Separate input string into separate answer strings.
    * Answer's within the input string are separated by ASCII value 04.
    * @param input Compound string
    * @param number Number of answers in input string
    * @return ArrayList<String> of correct answers
    */
   private ArrayList<String> separateAnswers(String input, int number) {
      int start = 0;
      int index;
      String temp;
      ArrayList<String> answerOptions = new ArrayList<String>();

      for (int i = 0; i < number; i++) {
         index = input.indexOf(4, start);
         temp = input.substring(start, index);
         start = index + 1;
         answerOptions.add(temp);
      } // End for

      return answerOptions;
   } // End separateAnswers

   /*
    * Hello, I would really like to stop talking to you. Honestly, I feel like
    * I've wasted the last hour of my life. I feel dummer for talking to you.
    * This conversation has done nothing but contribute to the heat death of
    * the universe, and you know what? My CPU is already over 200 degrees!! So
    * yeah. 900 to you.
    */
   //**************************************************************/
   /**
    * Send disconnect request to server
    * @param alias Username
    */
   public void sendDisconnectRequest(String alias) {
      try {
         out.writeInt(900);
         out.writeBytes(alias);
      } catch (IOException e) {
         System.err.println("Failed to send 900 message");
         //System.exit(-1);
      } // End Try/Catch
   } // End sendDisconnectRequest

   //**************************************************************/
   /**
    * Chekck if client socket is open.
    * @return <code>true</code> if socket is connected.
    */
   public boolean isOpen() {
      //it's open, but is anything on sale?
      return clientSocket.isConnected();
   } //End isOpen
} // End ConnectionManager

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/**********************************************************
 * Student name: Benaiah Henry
 * Course: COSC
 * Package: Server
 * File name: ConnectionHandler.java
 * Purpose: Thread for checking the network connection on
 *		      the server by calling the server update() function.
 *
 * Assumptions: None known.
 *
 * Limitations: None known.
 *
 * Development Computer: Dell Dimenstion E520
 * Operating System: Ubuntu 9.0
 * Integrated Development Environment (IDE): Netbeans IDE 6.7.1
 * Compiler: javac
 **************************************************************/
/**
 * This class checks the network for (among other things) hamsters, wild rats,
 * Bull Wievels, your old roomate, and spinach (seriously, somebody has to check
 * for spinach). It doesn't return anything if it finds them, so I assume it
 * removes them, but judging by the length of this class, I'm betting it just
 * points and laughs.
 * @author benaiah
 */
public class CheckNetwork extends Thread {

   ConnectionHandler connection;

   CheckNetwork(ConnectionHandler connectionH) {
      connection = connectionH;
   }

   @Override
   public void run() {
      while (true) {
         connection.checkForClients();
         connection.update();
         try {
            //point and laugh
            wait(100);
         } catch (InterruptedException e) {
            //that's right. This computer is impatient.
            //can't even wait around for a bunny to hop
            //away. Although, the old roomates CAN be hard
            //to move...
            System.out.println("Wait failed");
         }
      }

   }
} //the final parenthesis, golden and sweet: End of class is so neat!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**********************************************************
* Student Name: Benaiah Henry
* Course: COSC 4303
* Package: Server
* File name: ConnectionHandler.java
*
* Purpose:
*
* Development Computer: Dell Dimenstion E520
* Operating System: Ubuntu 9.10
* Integrated Development Environment (IDE): Netbeans IDE 6.7.1
* Compiler: javac
**************************************************************/
import java.net.*;
import java.io.*;
import java.util.*;

 

/**
* This handles the connection (not MANAGE, HANDLE) Management is an entirely
* different class which probably involves lots of pointy ears, walking around,
* and looking for the token ring under the desk (it’s very small and hard to
* find). But that’s not this class.
*
* This class is more like Dogbert. It smacks you upside the head, tells you
* things you need to know but won’t listen to, and walks away with the money.
* That’s what happens when we throw an exception here – Dogbert takes the money.
* @author Benaiah Henry
*/
public class ConnectionHandler {

ServerSocket serverSocket;
ResultHandler resultHandler;
String serverIP;
ArrayList<ConnectedUser> connectedUsers;
//ArrayList<ServerSocket> serverSockets;
public static final int DEFAULT_PORT = 1234;
public static final int MAX_CLIENTS = 500;
public static final int ACCEPT_TIMEOUT_LENGTH = 10;
public static final int SHORT_STRING = 32;

/**
*
* @throws java.io.IOException
*/
public ConnectionHandler(ResultHandler resultH) {
resultHandler = resultH;
try {
connectedUsers = new ArrayList<ConnectedUser>();
//serverSockets = new ArrayList<ServerSocket>();

InetAddress localIP = InetAddress.getLocalHost();
serverIP = localIP.getHostAddress();

serverSocket = new ServerSocket(DEFAULT_PORT, MAX_CLIENTS);

serverSocket.setSoTimeout(5);

} catch (IOException e) {
System.err.println(“Failed to create ServerSocket”);
} // End Try/Catch
} // End Constructor

/*
* Have you ever been bothered by how none of the clocks anywhere agree
* with each other? Have you ever just wanted a short little method
* that would synchronize everything? That would just update and make
* standardized time work? Yes we can!
* But this is not that method…
*/

//**************************************************************/
/**
* Checks for new data from all clients
*/
public void update() {
ConnectedUser temp = null;

for (int i = 0; i < connectedUsers.size(); i++) {
temp = connectedUsers.get(i);
readFromClient(temp.getSocket(), temp.getDataInputStream(), temp.getDataOutputStream(), i);
} // End for

} // End update

//**************************************************************/
/**
* Checks a serverSocket for new client connections
* And Asks accounting department to cut check to our wonderful clients
*
*/
public void checkForClients() {
DataOutputStream out;
DataInputStream in;
Socket connection;
InetAddress tempIP;
String IP;

try {

connection = serverSocket.accept();
//connection.getChannel().configureBlocking(false);

//System.err.println(“after connection made”);

in = new DataInputStream(connection.getInputStream());
out = new DataOutputStream(connection.getOutputStream());
tempIP = connection.getInetAddress();
IP = tempIP.toString();

//System.err.println(“after ip string”);

// create a new user ex nihilo
connectedUsers.add(new ConnectedUser(IP, null, connection, in, out));

//System.err.println(“after add user”);
} catch (SocketTimeoutException e) {
System.err.println(“accept timeout – continuing execution”);
} catch (IOException e) {
System.err.println(“socket accept failed”);
} // End Try/Catch
} // End checkForClients

//**************************************************************/
/**
*
* @param connection The socket to read from
* @param in    The DataInputStream of the connection
* @param out The DataOutputStream of the connection
* @param index Index of the client to read from
*/
public void readFromClient(Socket connection, DataInputStream in, DataOutputStream out, int index) {
int msgTypeID;

try {
connection.setSoTimeout(5);
msgTypeID = in.readInt();

switch (msgTypeID) {
case 100:
process100(in, index);
break;
case 300:
process300(in, index);
break;
case 900:
process900(index, connection, in, out);
break;
default:
System.err.println(“Invalid message code”);
break;
} // End switch
} catch (IOException e) {
System.err.println(“No data from client”);
} // End Try/Catch
}// End readFromClient

/**
* The wonderful processing method
* @param in A DataInputStream
* @param index Index of client
*/
private void process100(DataInputStream in, int index) {
String alias = null;
byte[] temp = new byte[SHORT_STRING];

try {
for (int i = 0; i < SHORT_STRING; i++) {
temp[i] = in.readByte();
}
alias = new String(temp).trim();
connectedUsers.get(index).setAlias(alias);
System.out.println(alias);
} catch (IOException e) {
System.err.println(“Failed to process 100 message”);
}
}

/**
* The other wonderful processing method, but 3 times better than the first one
* @param in A DataInputStream
* @param index Client index
*/
private void process300(DataInputStream in, int index) {
int questionNum = 0;
boolean didAnswer = false;        // yes, I know this is bad grammar
int timeTaken = 0;                  // careful, there will be problems if the user takes longer than 49,710 days to answer
// if you think that’s too long, consider using ‘long’
String answer = null;
byte[] temp = new byte[SHORT_STRING];

try {
questionNum = in.readInt();
didAnswer = in.readBoolean();
timeTaken = in.readInt();
for (int i = 0; i < SHORT_STRING; i++) {
temp[i] = in.readByte();
} // End for
answer = new String(temp).trim();
} catch (Exception e) {
System.err.println(“Failed to process 300 message”);
} // End Try/catch

resultHandler.storeAnswer(questionNum, didAnswer, timeTaken, answer, connectedUsers.get(index).getIPAddress());
} // End process300

/*
* Some of you may be wondering why process900 sends 999. Let me explain:
* Process 0 was created.
* process 0 begot process 100. Process 0 lived for
* 425 seconds and had other sons and daughters.
* Process 100 begot process 200. Process 100 lived for
* 511 seconds and had other sons and daughters.
* Process 200 begot process 300. Process 200 lived for
* 441 seconds and had other sons and daughters.
* Process 300 begot process 400. Process 300 lived for
* 225 seconds and had other sons and daughters.
* Process 400 begot process 500. Process 500 lived for
* 311 seconds and had other sons and daughters.
* Process 500 begot process 600. Now process 500 lived in the days of
* Windows ME. Dark were the times, and wild ran the memory manager.
* Process 500 lived 23 seconds and had no other children. Then it seg-faulted.
* Process 600 begot process 700. Process 600 lived for
* 259 seconds and had other sons and daughters.
* Process 700 begot process 800, who was lost in the upgrade to Vista.
* Process 700 begot process 900 (after confirming “allow” 71942 times.
* Children can be quite a security risk). Process 700 lived for
* 111 seconds and had other sons and daughters.
*
* Now process 900 walked with the kernel, and had many sons
* and daughters. It was granted a large memory footprint, and the
* exclusive use of 2 CPU cores, plus direct access to the PCI bus.
* Having so much wealth to manage, Process 900 diligently instructed
* his children, giving to some 10mb, to other 100mb, and to some whole
* gigabytes of memory. Thus was process 999, son of process 900,
* alloted communication with the first 13 pins of the card in 2nd PCI
* slot (which happens to be the NIC), and is thus responsible for
* for sending poetry, free chicken sandwich coupons, and instructions
* on building to-scale parking garages on the kitchen table without
* creating multi-car pileups.
*/

//**************************************************************/
/**
*
* Closes the connections
* @param index Index of client to close connections for
* @param connection The socket of the client
* @param in DataInputStream of connection
* @param out DataOutputStream of connection
*/
private void process900(int index, Socket connection, DataInputStream in, DataOutputStream out) {
send999(connectedUsers.get(index).getAlias(), out);

try {
in.close();
out.close();
connection.close();
} catch (Exception e) {
System.err.printf(“Failed to close connection for client at IP address: %s”, connection.getInetAddress().toString());
} // End Try/Catch
} // End process900

//**************************************************************/
/**
* Send Connection has been closed
* @param alias Username of client
* @param out DataOutputStream of client
*/
private void send999(String alias, DataOutputStream out) {
try {
out.writeInt(999);
writeString(alias, SHORT_STRING, out);
} catch (IOException e) {
System.err.println(“Failed to send 999 message”);
} // End Try/Catch
} // End send999

/**
* Writes strings to a DataOutputStream.  Either truncates at size, or pads with 0’s to size.
*
* Cutting a string would be more fun, but such is life
*
* @param s
* @param size
* @param out
*/
private void writeString(String s, int size, DataOutputStream out) {
try {
if (s.length() < (size – 1)) {
out.writeBytes(s);

for (int i = 0; i < (size – s.length()); i++) {
out.writeByte(0);
} // End for
} else if (s.length() > (size – 1)) {
s = s.trim().substring(0, (size – 1));
out.writeBytes(s);
out.writeByte(0);
} else {
out.writeBytes(s);
out.writeByte(0);
} // End if/else if/else
} catch (IOException e) {
System.err.println(“Write failed”);
System.exit(-1);
} // End Try/Catch
} // End writeString

//**************************************************************/
/**
* Send the question to all clients
* @param questionNum Number of the question
* @param questionType Type of question as an int
* @param timeLimit Time limit on question
* @param tallyMode Force tally mode
* @param optionCount Number of answer options
* @param questionText The question
* @param answerOptions All answer options concatenated and separated by ascii “04”
*/
public void sendQuestion(int questionNum, int questionType, int timeLimit, boolean tallyMode, int optionCount, String questionText, String answerOptions) {
ConnectedUser temp = null;
DataOutputStream out;

try {
for (int i = 0; i < connectedUsers.size(); i++) {
temp = connectedUsers.get(i);
out = temp.getDataOutputStream();

out.writeInt(200);
out.writeInt(questionNum);
out.writeInt(questionType);
out.writeInt(timeLimit);
out.writeBoolean(tallyMode);
out.writeInt(optionCount);
writeString(questionText, 256, out);
writeString(answerOptions, 256, out);
} // End for
} catch (IOException e) {
System.err.printf(“Failed to send 200 message to IP address %s”, temp.getSocket().getInetAddress().toString());
} // End Try/Catch
} // End SendQuestion

//The llama in the sky has recieved your request
//but your question is judged as causing unrest
//the words are malicious
//puncuation sadicious
//we’ll have to correct for success

//**************************************************************/
/**
* Send the correct answer to clients
* @param isCorrect Whether the answer was correct
* @param timeTaken How long it took to answer
* @param submittedAnswer Client’s submitted answer
* @param correctAnswer Correct answer
*/
public void sendGradedQuestion(boolean isCorrect, int timeTaken, String submittedAnswer, String correctAnswer) {
ConnectedUser temp = null;
DataOutputStream out;

try {
for (int i = 0; i < connectedUsers.size(); i++) {
temp = connectedUsers.get(i);
out = temp.getDataOutputStream(); //check for actual function name

//we sent a 400 (I don’t know why)
//I would have chosen 3,4, or pi
//but no one asked me
//or revealed the design
//no diagrams, no tree
//(they charged a $10 fine)
out.writeInt(400);
out.writeBoolean(isCorrect);
out.writeInt(timeTaken);
writeString(submittedAnswer, 32, out);
writeString(correctAnswer, 32, out);
} // End for
} catch (IOException e) {
System.err.println(“Failed to send 400 message to all clients”);
} // End Try/Catch
}// End sendGradedQuestion

//**************************************************************/
/**
* Send notification of end of set to all clients
*/
public void sendEndOfSet() {
ConnectedUser temp = null;
DataOutputStream out;

try {
for (int i = 0; i < connectedUsers.size(); i++) {
temp = connectedUsers.get(i);
out = temp.getDataOutputStream();

out.writeInt(500);
} // End for
} catch (IOException e) {
System.err.println(“Failed to send 500 message to all clients”);
} // End Try/Catch
}// End sendEndOfSet

//**************************************************************/

public String getServerIP() {

return serverIP;
} // End getServerIP

//**************************************************************/

public int getConnectedUserCount() {

return connectedUsers.size();
} // End getConnectedUserCount
}// End ConnectionHandler

Blog at WordPress.com.