Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I need help with this Java Assignment. Thanks Create a chat server-client pair w

ID: 3841834 • Letter: I

Question

I need help with this Java Assignment. Thanks

Create a chat server-client pair with a GUI that will allow users to send private plain-text messages to a user of their choice as well as group messages to all connected clients. REQUIREMENTS Create a group chat server that clients will connect to The default behavior when a message is sent from a client is that it goes through the server and the server sends the message to ALL connected recipients The client should have the option of sending a private message, by specifying who they want to send a message to

Explanation / Answer

Hi

Please find teh codd below for the Multichat server In which

The code mainly contain 5 classes which are as below

1-ChatMessage.java

2-Server.java

3-Client.java

4-ServerGUI.java

5-ClientGUI.java

***************ChatMessage.java class******************

package client;

import java.io.Serializable;
/*
* This class defines the different type of messages that will be exchanged between the
* Clients and the Server.
* When talking from a Java Client to a Java Server a lot easier to pass Java objects, no
* need to count bytes or to wait for a line feed at the end of the frame
*/
public class ChatMessage implements Serializable {

   protected static final long serialVersionUID = 1112122200L;

   // The different types of message sent by the Client
   // WHOISIN to receive the list of the users connected
   // MESSAGE an ordinary message
   // LOGOUT to disconnect from the Server
   static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2;
   private int type;
   private String message;
  
   // constructor
   ChatMessage(int type, String message) {
       this.type = type;
       this.message = message;
   }
  
   // getters
   int getType() {
       return type;
   }
   String getMessage() {
       return message;
   }
}

***************************************Server.java class***********************

package client;

import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;

import server.ServerGUI;

/*
* The server that can be run both as a console application or a GUI
*/
public class Server {
   // a unique ID for each connection
   private static int uniqueId;
   // an ArrayList to keep the list of the Client
   private ArrayList<ClientThread> al;
   // if I am in a GUI
   private ServerGUI sg;
   // to display time
   private SimpleDateFormat sdf;
   // the port number to listen for connection
   private int port;
   // the boolean that will be turned of to stop the server
   private boolean keepGoing;
  

   /*
   * server constructor that receive the port to listen to for connection as parameter
   * in console
   */
   public Server(int port) {
       this(port, null);
   }
  
   public Server(int port, ServerGUI sg) {
       // GUI or not
       this.sg = sg;
       // the port
       this.port = port;
       // to display hh:mm:ss
       sdf = new SimpleDateFormat("HH:mm:ss");
       // ArrayList for the Client list
       al = new ArrayList<ClientThread>();
   }
  
   public void start() {
       keepGoing = true;
       /* create socket server and wait for connection requests */
       try
       {
           // the socket used by the server
           ServerSocket serverSocket = new ServerSocket(port);

           // infinite loop to wait for connections
           while(keepGoing)
           {
               // format message saying we are waiting
               display("Server waiting for Clients on port " + port + ".");
              
               Socket socket = serverSocket.accept();     // accept connection
               // if I was asked to stop
               if(!keepGoing)
                   break;
               ClientThread t = new ClientThread(socket); // make a thread of it
               al.add(t);                                   // save it in the ArrayList
               t.start();
           }
           // I was asked to stop
           try {
               serverSocket.close();
               for(int i = 0; i < al.size(); ++i) {
                   ClientThread tc = al.get(i);
                   try {
                   tc.sInput.close();
                   tc.sOutput.close();
                   tc.socket.close();
                   }
                   catch(IOException ioE) {
                       // not much I can do
                   }
               }
           }
           catch(Exception e) {
               display("Exception closing the server and clients: " + e);
           }
       }
       // something went bad
       catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + " ";
           display(msg);
       }
   }      
/*
* For the GUI to stop the server
*/
   public void stop() {
       keepGoing = false;
       // connect to myself as Client to exit statement
       // Socket socket = serverSocket.accept();
       try {
           new Socket("localhost", port);
       }
       catch(Exception e) {
           // nothing I can really do
       }
   }
   /*
   * Display an event (not a message) to the console or the GUI
   */
   private void display(String msg) {
       String time = sdf.format(new Date()) + " " + msg;
       if(sg == null)
           System.out.println(time);
       else
           sg.appendEvent(time + " ");
   }
   /*
   * to broadcast a message to all Clients
   */
   private synchronized void broadcast(String message) {
       // add HH:mm:ss and to the message
       String time = sdf.format(new Date());
       String messageLf = time + " " + message + " ";
       // display message on console or GUI
       if(sg == null)
           System.out.print(messageLf);
       else
           sg.appendRoom(messageLf); // append in the room window
      
       // we loop in reverse order in case we would have to remove a Client
       // because it has disconnected
       for(int i = al.size(); --i >= 0;) {
           ClientThread ct = al.get(i);
           // try to write to the Client if it fails remove it from the list
           if(!ct.writeMsg(messageLf)) {
               al.remove(i);
               display("Disconnected Client " + ct.username + " removed from list.");
           }
       }
   }

   // for a client who logoff using the LOGOUT message
   synchronized void remove(int id) {
       // scan the array list until we found the Id
       for(int i = 0; i < al.size(); ++i) {
           ClientThread ct = al.get(i);
           // found it
           if(ct.id == id) {
               al.remove(i);
               return;
           }
       }
   }
  
   /*
   * To run as a console application just open a console window and:
   * > java Server
   * > java Server portNumber
   * If the port number is not specified 1500 is used
   */
   public static void main(String[] args) {
       // start server on port 1500 unless a PortNumber is specified
       int portNumber = 1500;
       switch(args.length) {
           case 1:
               try {
                   portNumber = Integer.parseInt(args[0]);
               }
               catch(Exception e) {
                   System.out.println("Invalid port number.");
                   System.out.println("Usage is: > java Server [portNumber]");
                   return;
               }
           case 0:
               break;
           default:
               System.out.println("Usage is: > java Server [portNumber]");
               return;
              
       }
       // create a server object and start it
       Server server = new Server(portNumber);
       server.start();
   }

   /** One instance of this thread will run for each client */
   class ClientThread extends Thread {
       // the socket where to listen/talk
       Socket socket;
       ObjectInputStream sInput;
       ObjectOutputStream sOutput;
       // my unique id (easier for deconnection)
       int id;
       // the Username of the Client
       String username;
       // the only type of message a will receive
       ChatMessage cm;
       // the date I connect
       String date;

       // Constructore
       ClientThread(Socket socket) {
           // a unique id
           id = ++uniqueId;
           this.socket = socket;
           /* Creating both Data Stream */
           System.out.println("Thread trying to create Object Input/Output Streams");
           try
           {
               // create output first
               sOutput = new ObjectOutputStream(socket.getOutputStream());
               sInput = new ObjectInputStream(socket.getInputStream());
               // read the username
               username = (String) sInput.readObject();
               display(username + " just connected.");
           }
           catch (IOException e) {
               display("Exception creating new Input/output Streams: " + e);
               return;
           }
           // have to catch ClassNotFoundException
           // but I read a String, I am sure it will work
           catch (ClassNotFoundException e) {
           }
date = new Date().toString() + " ";
       }

       // what will run forever
       public void run() {
           // to loop until LOGOUT
           boolean keepGoing = true;
           while(keepGoing) {
               // read a String (which is an object)
               try {
                   cm = (ChatMessage) sInput.readObject();
               }
               catch (IOException e) {
                   display(username + " Exception reading Streams: " + e);
                   break;              
               }
               catch(ClassNotFoundException e2) {
                   break;
               }
               // the messaage part of the ChatMessage
               String message = cm.getMessage();

               // Switch on the type of message receive
               switch(cm.getType()) {

               case ChatMessage.MESSAGE:
                   broadcast(username + ": " + message);
                   break;
               case ChatMessage.LOGOUT:
                   display(username + " disconnected with a LOGOUT message.");
                   keepGoing = false;
                   break;
               case ChatMessage.WHOISIN:
                   writeMsg("List of the users connected at " + sdf.format(new Date()) + " ");
                   // scan al the users connected
                   for(int i = 0; i < al.size(); ++i) {
                       ClientThread ct = al.get(i);
                       writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
                   }
                   break;
               }
           }
           // remove myself from the arrayList containing the list of the
           // connected Clients
           remove(id);
           close();
       }
      
       // try to close everything
       private void close() {
           // try to close the connection
           try {
               if(sOutput != null) sOutput.close();
           }
           catch(Exception e) {}
           try {
               if(sInput != null) sInput.close();
           }
           catch(Exception e) {};
           try {
               if(socket != null) socket.close();
           }
           catch (Exception e) {}
       }

       /*
       * Write a String to the Client output stream
       */
       private boolean writeMsg(String msg) {
           // if Client is still connected send the message to it
           if(!socket.isConnected()) {
               close();
               return false;
           }
           // write the message to the stream
           try {
               sOutput.writeObject(msg);
           }
           // if an error occurs, do not abort just inform the user
           catch(IOException e) {
               display("Error sending message to " + username);
               display(e.toString());
           }
           return true;
       }
   }
}

*****************************Client.java class**********************

package client;

import java.net.*;
import java.io.*;
import java.util.*;

/*
* The Client that can be run both as a console or a GUI
*/
public class Client {

   // for I/O
   private ObjectInputStream sInput;       // to read from the socket
   private ObjectOutputStream sOutput;       // to write on the socket
   private Socket socket;

   // if I use a GUI or not
   private ClientGUI cg;
  
   // the server, the port and the username
   private String server, username;
   private int port;

   /*
   * Constructor called by console mode
   * server: the server address
   * port: the port number
   * username: the username
   */
   Client(String server, int port, String username) {
       // which calls the common constructor with the GUI set to null
       this(server, port, username, null);
   }

   /*
   * Constructor call when used from a GUI
   * in console mode the ClienGUI parameter is null
   */
   Client(String server, int port, String username, ClientGUI cg) {
       this.server = server;
       this.port = port;
       this.username = username;
       // save if we are in GUI mode or not
       this.cg = cg;
   }
  
   /*
   * To start the dialog
   */
   public boolean start() {
       // try to connect to the server
       try {
           socket = new Socket(server, port);
       }
       // if it failed not much I can so
       catch(Exception ec) {
           display("Error connectiong to server:" + ec);
           return false;
       }
      
       String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
       display(msg);
  
       /* Creating both Data Stream */
       try
       {
           sInput = new ObjectInputStream(socket.getInputStream());
           sOutput = new ObjectOutputStream(socket.getOutputStream());
       }
       catch (IOException eIO) {
           display("Exception creating new Input/output Streams: " + eIO);
           return false;
       }

       // creates the Thread to listen from the server
       new ListenFromServer().start();
       // Send our username to the server this is the only message that we
       // will send as a String. All other messages will be ChatMessage objects
       try
       {
           sOutput.writeObject(username);
       }
       catch (IOException eIO) {
           display("Exception doing login : " + eIO);
           disconnect();
           return false;
       }
       // success we inform the caller that it worked
       return true;
   }

   /*
   * To send a message to the console or the GUI
   */
   private void display(String msg) {
       if(cg == null)
           System.out.println(msg); // println in console mode
       else
           cg.append(msg + " ");       // append to the ClientGUI JTextArea (or whatever)
   }
  
   /*
   * To send a message to the server
   */
   void sendMessage(ChatMessage msg) {
       try {
           sOutput.writeObject(msg);
       }
       catch(IOException e) {
           display("Exception writing to server: " + e);
       }
   }

   /*
   * When something goes wrong
   * Close the Input/Output streams and disconnect not much to do in the catch clause
   */
   private void disconnect() {
       try {
           if(sInput != null) sInput.close();
       }
       catch(Exception e) {} // not much else I can do
       try {
           if(sOutput != null) sOutput.close();
       }
       catch(Exception e) {} // not much else I can do
try{
           if(socket != null) socket.close();
       }
       catch(Exception e) {} // not much else I can do
      
       // inform the GUI
       if(cg != null)
           cg.connectionFailed();
          
   }
   /*
   * To start the Client in console mode use one of the following command
   * > java Client
   * > java Client username
   * > java Client username portNumber
   * > java Client username portNumber serverAddress
   * at the console prompt
   * If the portNumber is not specified 1500 is used
   * If the serverAddress is not specified "localHost" is used
   * If the username is not specified "Anonymous" is used
   * > java Client
   * is equivalent to
   * > java Client Anonymous 1500 localhost
   * are eqquivalent
   *
   * In console mode, if an error occurs the program simply stops
   * when a GUI id used, the GUI is informed of the disconnection
   */
   public static void main(String[] args) {
       // default values
       int portNumber = 1500;
       String serverAddress = "localhost";
       String userName = "Anonymous";

       // depending of the number of arguments provided we fall through
       switch(args.length) {
           // > javac Client username portNumber serverAddr
           case 3:
               serverAddress = args[2];
           // > javac Client username portNumber
           case 2:
               try {
                   portNumber = Integer.parseInt(args[1]);
               }
               catch(Exception e) {
                   System.out.println("Invalid port number.");
                   System.out.println("Usage is: > java Client [username] [portNumber] [serverAddress]");
                   return;
               }
           // > javac Client username
           case 1:
               userName = args[0];
           // > java Client
           case 0:
               break;
           // invalid number of arguments
           default:
               System.out.println("Usage is: > java Client [username] [portNumber] {serverAddress]");
           return;
       }
       // create the Client object
       Client client = new Client(serverAddress, portNumber, userName);
       // test if we can start the connection to the Server
       // if it failed nothing we can do
       if(!client.start())
           return;
      
       // wait for messages from user
       Scanner scan = new Scanner(System.in);
       // loop forever for message from the user
       while(true) {
           System.out.print("> ");
           // read message from user
           String msg = scan.nextLine();
           // logout if message is LOGOUT
           if(msg.equalsIgnoreCase("LOGOUT")) {
               client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, ""));
               // break to do the disconnect
               break;
           }
           // message WhoIsIn
           else if(msg.equalsIgnoreCase("WHOISIN")) {
               client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));              
           }
           else {               // default to ordinary message
               client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, msg));
           }
       }
       // done disconnect
       client.disconnect();  
   }

   /*
   * a class that waits for the message from the server and append them to the JTextArea
   * if we have a GUI or simply System.out.println() it in console mode
   */
   class ListenFromServer extends Thread {

       public void run() {
           while(true) {
               try {
                   String msg = (String) sInput.readObject();
                   // if console mode print the message and add back the prompt
                   if(cg == null) {
                       System.out.println(msg);
                       System.out.print("> ");
                   }
                   else {
                       cg.append(msg);
                   }
               }
               catch(IOException e) {
                   display("Server has close the connection: " + e);
                   if(cg != null)
                       cg.connectionFailed();
                   break;
               }
               // can't happen with a String object but need the catch anyhow
               catch(ClassNotFoundException e2) {
               }
           }
       }
   }
}

Please find serverGUI & clientGUI in comments section.as we have limitation in answring word.