diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..89163fe Binary files /dev/null and b/.DS_Store differ diff --git a/code/.DS_Store b/code/.DS_Store new file mode 100644 index 0000000..59392fd Binary files /dev/null and b/code/.DS_Store differ diff --git a/code/simplechat1/.DS_Store b/code/simplechat1/.DS_Store new file mode 100644 index 0000000..a98760a Binary files /dev/null and b/code/simplechat1/.DS_Store differ diff --git a/code/simplechat1/ClientConsole.java b/code/simplechat1/ClientConsole.java index c9bb4e9..6c076b7 100644 --- a/code/simplechat1/ClientConsole.java +++ b/code/simplechat1/ClientConsole.java @@ -41,11 +41,11 @@ public class ClientConsole implements ChatIF * @param host The host to connect to. * @param port The port to connect on. */ - public ClientConsole(String host, int port) + public ClientConsole(String host, int port, String loginID) { try { - client= new ChatClient(host, port, this); + client= new ChatClient(host, port, this, loginID); } catch(IOException exception) { @@ -73,6 +73,7 @@ public void accept() while (true) { message = fromConsole.readLine(); + client.handleMessageFromClientUI(message); } } @@ -104,19 +105,50 @@ public void display(String message) */ public static void main(String[] args) { + /*The first command line argument is the loginID, then the host, then the port*/ + String loginID =""; String host = ""; int port = 0; //The port number try { - host = args[0]; + loginID = args[0]; + } + catch(ArrayIndexOutOfBoundsException e) + { + /*if there is no argument, print an error message and exit*/ + System.out.println("No login id found, program quitting."); + System.exit(1); + + } + + try + { + host = args[1]; } catch(ArrayIndexOutOfBoundsException e) { host = "localhost"; } - ClientConsole chat= new ClientConsole(host, DEFAULT_PORT); - chat.accept(); //Wait for console data + + try + { + + port = Integer.parseInt(args[2]); //Get port from command line + ClientConsole chat= new ClientConsole(host, port, loginID); + chat.accept(); + + } + catch(Throwable t) + { + ClientConsole chat= new ClientConsole(host, DEFAULT_PORT, loginID); //Set port to 5555 + chat.accept(); + + } + + + + } } //End of ConsoleChat class diff --git a/code/simplechat1/EchoServer.java b/code/simplechat1/EchoServer.java index d4f3a1a..1f60bb6 100644 --- a/code/simplechat1/EchoServer.java +++ b/code/simplechat1/EchoServer.java @@ -4,6 +4,10 @@ import java.io.*; import ocsf.server.*; +import java.io.*; +import client.*; +import common.*; +import java.lang.*; /** * This class overrides some of the methods in the abstract @@ -23,6 +27,8 @@ public class EchoServer extends AbstractServer * The default port to listen on. */ final public static int DEFAULT_PORT = 5555; + + ChatIF serverUI; //Constructors **************************************************** @@ -31,9 +37,10 @@ public class EchoServer extends AbstractServer * * @param port The port number to connect on. */ - public EchoServer(int port) + public EchoServer(int port, ChatIF serverUI)throws IOException { super(port); + this.serverUI = serverUI; } @@ -45,11 +52,28 @@ public EchoServer(int port) * @param msg The message received from the client. * @param client The connection from which the message originated. */ + /*handles message from the client*/ + /*I haven't done, E7(c) iv,v since it is redundant given the way i've written my code. + + (iv)The #login command should only be allowed as the first command received after a client connects. If #login is received at any other time, the server shouldsend an error message back to the client. + This will never occur because handlemessagefromclientui in chatclient will catch any #login typed by the user for a different command and there is no other way for a user to send a message to the server than go through this method + + (v) If the #login command is not received as the first command, then the server should send an error message back to the client and terminate the client’s connection. Hint: use the method called close found in ConnnectionToClient. + This will never occur since I put sendtoserver #login loginID in the constructor of chatclient so it will always be the first command sent + + You will probably take marks off since I technically haven't done it but I just wanted to show that I wasn't being lazy or actually I was being lazy but lazy to do something that was redundant in the context of my implementation of simplechat. + */ public void handleMessageFromClient (Object msg, ConnectionToClient client) { - System.out.println("Message received: " + msg + " from " + client); - this.sendToAllClients(msg); + String message = msg.toString(); + if(message.contains("#login")){ + String loginID = message.replace("#login ",""); + client.setInfo("loginID", loginID); + }else{ + serverUI.display("Message received: " + msg + " from " + client); + this.sendToAllClients("<"+client.getInfo("loginID")+"> "+msg); + } } /** @@ -58,7 +82,7 @@ public EchoServer(int port) */ protected void serverStarted() { - System.out.println + serverUI.display ("Server listening for connections on port " + getPort()); } @@ -66,12 +90,87 @@ protected void serverStarted() * This method overrides the one in the superclass. Called * when the server stops listening for connections. */ + + /*Messages*/ protected void serverStopped() { - System.out.println + serverUI.display ("Server has stopped listening for connections."); } + + protected void clientConnected(ConnectionToClient client) { + serverUI.display + ("A client just joined ( ͡° ͜ʖ ͡°)"); + } + + synchronized protected void clientDisconnected(ConnectionToClient client) { + serverUI.display("The client has disconnected"); + } + + /*handles messages from serverui and does commands*/ + + public void handleMessageFromServerUI(String message) + { + if(message.contains("#")){ + if(message.contains("quit")){ + quit(); + } + + if(message.contains("stop")){ + stopListening(); + } + + if(message.contains("close")){ + try + { + close(); + } + catch(IOException e) {} + } + + if(message.contains("setport")){ + if(isListening()){ + serverUI.display("This operation is unavailable while the server is not stopped."); + }else{ + int portt = Integer.parseInt(message.replace("#setport","")); + setPort(portt); + } + } + + if(message.contains("start")){ + if(isListening()){ + serverUI.display("This operation is unavailable while the server is not stopped."); + }else{ + try + { + listen(); + } + catch(IOException e) {} + } + } + + if(message.contains("getport")){ + serverUI.display(String.valueOf(getPort())); + } + + + } + message = "SERVER MSG> "+ message; + this.sendToAllClients(message); + } + /*added a quit method similar to the one in chatclient but for the server*/ + public void quit() + { + try + { + close(); + } + catch(IOException e) {} + System.exit(0); + } + + //Class methods *************************************************** /** @@ -81,29 +180,10 @@ protected void serverStopped() * @param args[0] The port number to listen on. Defaults to 5555 * if no argument is entered. */ - public static void main(String[] args) - { - int port = 0; //Port to listen on - try - { - port = Integer.parseInt(args[0]); //Get port from command line - } - catch(Throwable t) - { - port = DEFAULT_PORT; //Set port to 5555 - } - - EchoServer sv = new EchoServer(port); - - try - { - sv.listen(); //Start listening for connections - } - catch (Exception ex) - { - System.out.println("ERROR - Could not listen for clients!"); - } - } + /*put an empty main method due to an error I was getting, please ignore it*/ + public static void main(String[] args) + {} + } //End of EchoServer class diff --git a/code/simplechat1/ServerConsole.java b/code/simplechat1/ServerConsole.java new file mode 100644 index 0000000..8beb6fb --- /dev/null +++ b/code/simplechat1/ServerConsole.java @@ -0,0 +1,102 @@ +import java.io.*; +import client.*; +import common.*; + + +public class ServerConsole implements ChatIF +{ + //Class variables ************************************************* + + /** + * The default port to connect on. + */ + final public static int DEFAULT_PORT = 5555; + + //Instance variables ********************************************** + + /** + * The instance of the client that created this ConsoleChat. + */ + EchoServer server; + + + //Constructors **************************************************** + public ServerConsole( int port) + { + try + { + server= new EchoServer(port, this); + } + catch(IOException exception) + { + System.out.println("Error: Can't setup connection!" + + " Terminating client."); + System.exit(1); + } + } + /*works similarly to the one in clientconsole*/ + public void accept() + { + try + { + BufferedReader fromConsole = + new BufferedReader(new InputStreamReader(System.in)); + String message; + + while (true) + { + message = fromConsole.readLine(); + + server.handleMessageFromServerUI(message); + } + } + catch (Exception ex) + { + System.out.println + ("Unexpected error while reading from console!"); + } + } + + /*works similarly to the one in clientconsole*/ + public void display(String message) + { + System.out.println("> " +message); + } + + + + /** + * This method is responsible for the creation of + * the server instance (there is no UI in this phase). + * + * @param args[0] The port number to listen on. Defaults to 5555 + * if no argument is entered. + */ + /*moved main method from echoserver to here and changed it so it would create a server console instead, serverconsole constructor calls echoserver constructor*/ + public static void main(String[] args) + { + int port = 0; //Port to listen on + + try + { + port = Integer.parseInt(args[0]); //Get port from command line + } + catch(Throwable t) + { + port = DEFAULT_PORT; //Set port to 5555 + } + + ServerConsole sc = new ServerConsole(port); + + try + { + sc.server.listen(); //Start listening for connections + } + catch (Exception ex) + { + System.out.println("ERROR - Could not listen for clients!"); + } + sc.accept(); + } + +} diff --git a/code/simplechat1/client/ChatClient.java b/code/simplechat1/client/ChatClient.java index fe1401e..bd9c698 100644 --- a/code/simplechat1/client/ChatClient.java +++ b/code/simplechat1/client/ChatClient.java @@ -26,6 +26,7 @@ public class ChatClient extends AbstractClient * the display method in the client. */ ChatIF clientUI; + String loginID; //Constructors **************************************************** @@ -36,14 +37,18 @@ public class ChatClient extends AbstractClient * @param host The server to connect to. * @param port The port number to connect on. * @param clientUI The interface type variable. + * @param LoginID */ - public ChatClient(String host, int port, ChatIF clientUI) + public ChatClient(String host, int port, ChatIF clientUI, String loginID) throws IOException { + /*added loginID, sends the login id to server upon creation of an instance of chatclient*/ super(host, port); //Call the superclass constructor this.clientUI = clientUI; + this.loginID = loginID; openConnection(); + sendToServer("#login "+loginID); } @@ -66,15 +71,72 @@ public void handleMessageFromServer(Object msg) */ public void handleMessageFromClientUI(String message) { - try - { - sendToServer(message); - } - catch(IOException e) - { - clientUI.display - ("Could not send message to server. Terminating client."); - quit(); + /*does various commands depending on whether a # is used*/ + if(message.contains("#")){ + if(message.contains("quit")){ + quit(); + } + + if(message.contains("logoff")){ + try + { + closeConnection(); + } + catch(IOException e) {} + } + + if(message.contains("sethost")){ + if(isConnected()){ + clientUI.display("This operation is unavailable while logged on."); + }else{ + setHost(message.replace("#sethost","")); + } + } + + if(message.contains("setport")){ + if(isConnected()){ + clientUI.display("This operation is unavailable while logged on."); + }else{ + int portt = Integer.parseInt(message.replace("#setport","")); + setPort(portt); + } + } + + if(message.contains("login")){ + if(isConnected()){ + clientUI.display("This operation is unavailable while logged on."); + }else{ + try + { + openConnection(); + } + catch(IOException e) {} + } + } + + if(message.contains("gethost")){ + clientUI.display(getHost()); + } + + if(message.contains("getport")){ + clientUI.display(String.valueOf(getPort())); + } + + + }else{ + try + { + + sendToServer(message); + + + } + catch(IOException e) + { + clientUI.display + ("Could not send message to server. Terminating client."); + quit(); + } } } @@ -90,5 +152,14 @@ public void quit() catch(IOException e) {} System.exit(0); } + + /*displays a message when connection is closed*/ + public void connectionClosed() { + clientUI.display("The connection has been closed"); + } + /*displays a message when an exception occurs*/ + protected void connectionException(Exception exception) { + clientUI.display("An error has occured, the connection has been closed"); + } } //End of ChatClient class diff --git a/code/simplechat1/common/.DS_Store b/code/simplechat1/common/.DS_Store new file mode 100644 index 0000000..f28c6e4 Binary files /dev/null and b/code/simplechat1/common/.DS_Store differ diff --git a/code/simplechat1/testcases.pdf b/code/simplechat1/testcases.pdf new file mode 100644 index 0000000..bcb5e75 Binary files /dev/null and b/code/simplechat1/testcases.pdf differ