scp-app

git clone git://git.codymlewis.com/scp-app.git
Log | Files | Refs | LICENSE

commit 1cbed5c430c9d87eb54ce25a3714fd4e21041e40
parent b0f73c9c8c146d6ed4239596f3070c79a0231e22
Author: Cody Lewis <luxdotsugi@gmail.com>
Date:   Sun, 19 Aug 2018 20:06:49 +1000

Cleaned up a few redundancies including the result class

Diffstat:
MChatClient.java | 53+++++++++++++++++++++++++++++++----------------------
MChatServer.java | 129++++++++++++++++++++++++++++++++++++++-----------------------------------------
MSCP.java | 103++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
MSCPException.java | 17+++++++++++++++--
ATimeDiffException.java | 26++++++++++++++++++++++++++
5 files changed, 236 insertions(+), 92 deletions(-)

diff --git a/ChatClient.java b/ChatClient.java @@ -37,12 +37,25 @@ public class ChatClient { System.out.print("Input a username: "); String username = console.next(); scpConnect(hostName, port, username); - System.out.println(in.readLine()); + System.out.println("Connected to SCP"); + String message; + while(true) { + System.out.print(recieveMessage()); + System.out.print("send a message: "); + message = console.next(); + if(message == "DISCONNECT") { + break; + } + out.println(scp.message("127.0.0.1", 3400, message)); + System.out.println("Server is typing..."); + } console.close(); + } catch(SCPException scpe) { + System.err.println(scpe.getMessage()); } catch(UnknownHostException uhe) { - System.err.println("Specified host does not exist"); + System.err.println(uhe.getMessage()); } catch(IOException ioe) { - System.err.println("Input/Output error"); + System.err.println(ioe.getMessage()); } } /** @@ -64,35 +77,31 @@ public class ChatClient { * @param username client specified username * @return true on packet send */ - private boolean scpConnect(String hostName, int port, String username) throws IOException { + private boolean scpConnect(String hostName, int port, String username) throws SCPException, IOException { String connectionString = scp.connect(username, hostName, port); out.println(connectionString); if(scpDecide(username)) { - scpAknowledge(username); + scpAcknowledge(username); return true; } return false; } - private boolean scpDecide(String username) throws IOException { - String inLine; - boolean accept = false; + private boolean scpDecide(String username) throws SCPException, IOException { + String inLine, packet = ""; while((inLine = in.readLine()).compareTo("SCP END") != 0) { - if(!accept) { - if(inLine.indexOf("SCP ACCEPT") > -1) { - accept = true; - } else { - throw new IOException(); - } - } - if(inLine.indexOf("USERNAME") > -1) { - if(inLine.indexOf(username) == -1) { - return false; - } - } + packet += inLine + "\n"; } - return true; + return scp.parseAccept(packet, username); } - private void scpAknowledge(String username) { + private void scpAcknowledge(String username) { out.println(scp.acknowledge(username, "127.0.0.1", 3400)); } + private String recieveMessage() throws SCPException, IOException { + String packet = ""; + String line = ""; + while((line = in.readLine()).compareTo("SCP END") != 0) { + packet += line + "\n"; + } + return scp.parseMessage(packet, "127.0.0.1", 3400); + } } diff --git a/ChatServer.java b/ChatServer.java @@ -21,8 +21,9 @@ public class ChatServer { private Socket cliSocket; private PrintWriter out; private BufferedReader in; - InetAddress hostInetAddress; - int port; + private InetAddress hostInetAddress; + private int port; + private String username; private static final int BACKLOG = 1; // Max length for queue of messages public static void main(String args[]) { ChatServer cs = new ChatServer(); @@ -39,36 +40,46 @@ public class ChatServer { port = args.length > 1 ? Integer.parseInt(args[1]) : 3400; String welcomeMessage = args.length > 2 ? args[2] : "Welcome to SCP"; System.out.println(String.format("Starting server on %s:%d", hostInetAddress.getHostAddress(), port)); - startSocket(hostInetAddress, port); + startSocket(); System.out.println("Started server"); hostConnection(welcomeMessage); + } catch(SCPException scpe) { + System.err.println(scpe.getMessage()); } catch(IOException ioe) { - System.err.println("Input/Output error"); + System.err.println(ioe.getMessage()); } } /** * Host a client connection * @param welcomeMessage the welcome message sent to the client */ - private void hostConnection(String welcomeMessage) throws IOException { - boolean disconnect = false; - while(!disconnect) { - System.out.println("Waiting for client to connect"); - acceptClient(); - System.out.println("Client successfully connected"); - System.out.println("Waiting for client to SCP connect"); - String username = clientConnect(); - if(username == "") { - cliSocket.close(); - System.out.println("Rejected client for time differential greater than 5"); - continue; - } - scpAccept(username); - if(acknowledged(username)) { - out.println(welcomeMessage); - System.out.println(String.format("User %s has connected to SCP", username)); + private void hostConnection(String welcomeMessage) throws SCPException, IOException { + System.out.println("Waiting for client to connect"); + acceptClient(); + System.out.println("Client successfully connected"); + System.out.println("Waiting for client to SCP connect"); + username = clientConnect(); + username = username.substring(1, username.length() - 1); // remove quotes + if(username == "") { + cliSocket.close(); + System.out.println("Rejected client for time differential greater than 5"); + } + scpAccept(); + if(acknowledged()) { + System.out.println(String.format("User %s has connected to SCP", username)); + Scanner console = new Scanner(System.in); + String message = welcomeMessage; + while(true) { + out.println(scp.message(hostInetAddress.getHostAddress(), port, message)); + System.out.println(String.format("%s is typing...", username)); + System.out.print(recieveMessage()); + System.out.print("Send a message: "); + message = console.next(); + if(message == "DISCONNECT") { + break; + } } - disconnect = true; + console.close(); } } /** @@ -77,8 +88,8 @@ public class ChatServer { * @param port The port to run the server on * @return True on successful start */ - private boolean startSocket(InetAddress hostAddress, int port) throws IOException { - serverSocket = new ServerSocket(port, BACKLOG, hostAddress); + private boolean startSocket() throws IOException { + serverSocket = new ServerSocket(port, BACKLOG, hostInetAddress); return true; } /** @@ -95,39 +106,17 @@ public class ChatServer { * Recieve a scp connection * @return Client's username */ - private String clientConnect() throws IOException { - String inLine; - boolean isScpConnect = false; - String username = ""; + private String clientConnect() throws SCPException, IOException { + String inLine, result = "", packet = ""; while((inLine = in.readLine()).compareTo("SCP END") != 0) { - if(!isScpConnect) { - if(inLine.indexOf("SCP CONNECT") < 0) { - throw new IOException(); - } else { - isScpConnect = true; - } - } else { - if(inLine.indexOf("REQUESTCREATED") > -1) { - int requestTime = Integer.parseInt(inLine.substring(inLine.indexOf(" ") + 1)); - int timeDiff = findTimeDiff(requestTime); - if(timeDiff > 5) { - reject(timeDiff); - break; - } - } else if(inLine.indexOf("USERNAME") > -1) { - username = inLine.substring(inLine.indexOf(" ") + 1); - } - } + packet += inLine + "\n"; } - return username; - } - /** - * Find passes epoch time from specified time - * @param otherTime specified time - * @return The difference in times - */ - private int findTimeDiff(int otherTime) { - return Math.abs((int)Instant.now().getEpochSecond() - otherTime); + try { + result = scp.parseConnect(packet); + } catch(TimeDiffException tde) { + reject(tde.getTimeDiff()); + } + return result; } /** * Reject client for taking too long @@ -140,21 +129,27 @@ public class ChatServer { * Send a SCP connect message to the client * @param username user specified name */ - private void scpAccept(String username) { + private void scpAccept() { out.println(scp.accept(username, "127.0.0.1", 3400)); } - private boolean acknowledged(String username) throws IOException { - String inLine; - boolean firstLine = true; + /** + * Check if the client has been acknowledged by the server + */ + private boolean acknowledged() throws SCPException, IOException { + String inLine, packet = ""; while((inLine = in.readLine()).compareTo("SCP END") != 0) { - if(firstLine) { - if(inLine.indexOf("SCP ACKNOWLEDGE") > -1) { - firstLine = false; - } else { - return false; - } - } + packet += inLine; } - return true; + return scp.parseAcknowledge(packet) == "success"; + } + /** + * Recieve a message from the client + */ + private String recieveMessage() throws SCPException, IOException { + String packet = "", line = ""; + while((line = in.readLine()).compareTo("SCP END") != 0) { + packet += line + "\n"; + } + return scp.parseMessage(packet, "127.0.0.1", 3400); } } diff --git a/SCP.java b/SCP.java @@ -1,4 +1,7 @@ import java.time.Instant; +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.IOException; /** * SCP.java - Seng3400A1 * SCP parsing/packet creating library @@ -87,5 +90,103 @@ public class SCP { return "SCP DISCONNECT\nSCP END"; } // packet parsing - + /** + * Parse a SCP connect packet + * @param packet the connect packet + * @return A Result object containing final status and corresponding data + */ + public String parseConnect(String packet) throws TimeDiffException, SCPException, IOException { + String username = ""; + BufferedReader sstream = new BufferedReader(new StringReader(packet)); + boolean firstLine = true; + String line; + while((line = sstream.readLine()) != null) { + if(firstLine) { + if(line.indexOf("SCP CONNECT") < 0) { + sstream.close(); + throw new SCPException("SCP CONNECT", line); + } + firstLine = false; + } + if(line.indexOf("REQUESTCREATED") > -1) { + int requestTime = Integer.parseInt(line.substring(line.indexOf(" ") + 1)); + int timeDiff = findTimeDiff(requestTime); + if(timeDiff > 5) { + sstream.close(); + throw new TimeDiffException(timeDiff); + } + } else if(line.indexOf("USERNAME") > -1) { + username = line.substring(line.indexOf(" ") + 1); + } + } + sstream.close(); + return username; + } + /** + * Find passes epoch time from specified time + * @param otherTime specified time + * @return The difference in times + */ + private int findTimeDiff(int otherTime) { + return Math.abs((int)Instant.now().getEpochSecond() - otherTime); + } + public String parseAcknowledge(String packet) throws SCPException { + if (packet.indexOf("SCP ACKNOWLEDGE") > -1) { + return "success"; + } + throw new SCPException("SCP ACKNOWLEDGE", packet); + } + public boolean parseAccept(String packet, String username) throws SCPException, IOException { + boolean accept = false; + BufferedReader sstream = new BufferedReader(new StringReader(packet)); + String line; + while((line = sstream.readLine()) != null) { + if(!accept) { + if(line.indexOf("SCP ACCEPT") > -1) { + accept = true; + } else { + throw new SCPException("SCP ACCEPT", line); + } + } + if(line.indexOf("USERNAME") > -1) { + if(line.indexOf(username) == -1) { + throw new SCPException(username, line); + } + } + } + return true; + } + public String parseMessage(String packet, String address, int port) throws SCPException, IOException { + boolean firstLine = true; + BufferedReader sstream = new BufferedReader(new StringReader(packet)); + String line; + String message = ""; + while((line = sstream.readLine()) != null) { + if(firstLine) { + if(line.indexOf("SCP CHAT") == -1) { + throw new SCPException("SCP CHAT", line); + } + firstLine = false; + } + if(line.indexOf("REMOTEADDRESS") > -1) { + if(line.substring(line.indexOf(" ") + 1).indexOf(address) == -1) { + throw new SCPException("REMOTEADDRESS " + address, line); + } + } else if(line.indexOf("REMOTEPORT") > -1) { + if(Integer.parseInt(line.substring(line.indexOf(" ") + 1)) != port) { + throw new SCPException("REMOTEPORT " + port, line); + } + } else if(line.indexOf("MESSAGECONTENT") > -1) { + message = packet.substring(packet.indexOf("\n\n") + 2); + break; + } + } + return message; + } + public String parseDisconnect(String packet) throws SCPException { + if (packet.indexOf("SCP DISCONNECT") > -1) { + return "success"; + } + throw new SCPException("SCP DISCONNECT", packet); + } } \ No newline at end of file diff --git a/SCPException.java b/SCPException.java @@ -7,8 +7,21 @@ */ public class SCPException extends Exception { static final long serialVersionUID = 1L; + /** + * Default constructor + */ public SCPException() {} - public SCPException(String message) { - super(message); + /** + * Input constructor + * @param message the exception's message + */ + public SCPException(String message) { super(message); } + /** + * Sentence input constructor + * @param expected the String that was Expected + * @param received the String that was recieved + */ + public SCPException(String expected, String received) { + super("Expected " + expected + " but got " + received); } } \ No newline at end of file diff --git a/TimeDiffException.java b/TimeDiffException.java @@ -0,0 +1,25 @@ +/** + * TimeDiffException.java - Seng3400A1 + * Exception for the Time Diff error from SCP parsing + * + * @author Cody Lewis + * @since 2018-08-19 + */ +public class TimeDiffException extends Exception { + static final long serialVersionUID = 1L; + private int timeDiff; + /** + * Default constructor + */ + public TimeDiffException() { timeDiff = 0; } + /** + * Input constructor + * @param timeDiff the difference in the times + */ + public TimeDiffException(int timeDiff) { this.timeDiff = timeDiff; } + /** + * Query for the time difference + * @return the Difference in times + */ + public int getTimeDiff() { return timeDiff; } +}+ \ No newline at end of file