scp-app

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

commit 0d57f08c912af44e2158b91a081c54e7c4ae4ca8
parent 07e82437a6c70757c817303c7cf2ffe91ef13e9f
Author: Cody Lewis <luxdotsugi@gmail.com>
Date:   Tue, 21 Aug 2018 10:07:30 +1000

The program works completely

Diffstat:
MChat.java | 8+++++++-
MChatClient.java | 21+++++++++++++++++----
MChatServer.java | 23++++++++++++++---------
MSCP.java | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 129 insertions(+), 20 deletions(-)

diff --git a/Chat.java b/Chat.java @@ -20,6 +20,9 @@ public class Chat { protected InetAddress address; protected int port; protected String username; + /** + * Default Constructor + */ public Chat() { scp = new SCP(); console = new Scanner(System.in); @@ -53,8 +56,11 @@ public class Chat { if(scp.parseAcknowledge(packet)) { return "ACKNOWLEDGE"; } - return scp.parseMessage(packet, "127.0.0.1", 3400); + return scp.parseMessage(packet, address.getHostAddress(), port); } + /** + * Send a SCP disconnect to the other user + */ protected void disconnect() { out.println(scp.disconnect()); } diff --git a/ChatClient.java b/ChatClient.java @@ -1,4 +1,3 @@ -import java.util.Scanner; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.InputStreamReader; @@ -14,6 +13,10 @@ import java.net.UnknownHostException; * @since 2018-08-10 */ public class ChatClient extends Chat { + /** + * The main thread + * @param args command line arguments + */ public static void main(String args[]) { ChatClient cc = new ChatClient(); cc.run(args); @@ -25,7 +28,7 @@ public class ChatClient extends Chat { */ public void run(String args[]) { try { - address = args.length > 0 ? InetAddress.getLocalHost() : InetAddress.getLocalHost(); + address = args.length > 0 ? InetAddress.getByName(args[0]) : InetAddress.getLocalHost(); port = args.length > 1 ? Integer.parseInt(args[1]) : 3400; if(port < 1024) { throw new SCPException("Using a port number 1023 or lower may interrupt system operations"); @@ -42,8 +45,10 @@ public class ChatClient extends Chat { boolean disconnect = false; while(!disconnect) { recievedMessage = recieveMessage(); + System.out.println(); if(recievedMessage == "DISCONNECT") { out.println(scp.acknowledge()); + System.out.println("Server disconnected"); disconnect = true; break; } @@ -53,6 +58,7 @@ public class ChatClient extends Chat { if(message.compareTo("DISCONNECT") == 0) { out.println(scp.disconnect()); if(recieveMessage().compareTo("ACKNOWLEDGE") == 0) { + System.out.println("Disconnected from server"); disconnect = true; break; } else { @@ -60,7 +66,7 @@ public class ChatClient extends Chat { } } out.println(scp.message(address.getHostAddress(), port, message)); - System.out.println("Server is typing..."); + System.out.print("Server is typing..."); } console.close(); } catch(SCPException scpe) { @@ -99,13 +105,20 @@ public class ChatClient extends Chat { } return false; } + /** + * Find out whether the server accepted or rejected by the server + * @return true if accepted, false if rejected + */ private boolean scpDecide() throws SCPException, IOException { String inLine, packet = ""; while((inLine = in.readLine()).compareTo("SCP END") != 0) { packet += inLine + "\n"; } - return scp.parseAccept(packet, username); + return scp.parseAccept(packet, username, address.getHostAddress(), port); } + /** + * Send a acknowledge SCP packet to the server + */ private void scpAcknowledge() { out.println(scp.acknowledge(username, address.getHostAddress(), port)); } diff --git a/ChatServer.java b/ChatServer.java @@ -1,5 +1,3 @@ -import java.util.Scanner; -import java.time.Instant; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.InputStreamReader; @@ -7,18 +5,22 @@ import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.InetAddress; -import java.net.UnknownHostException; /** * ChatServer.java - Seng3400A1 * A socket based half duplex chat server * * @author Cody Lewis * @since 2018-08-10 + * TODO make it so if one program errors, the other does not crash */ public class ChatServer extends Chat { private ServerSocket serverSocket; private String username; private static final int BACKLOG = 1; // Max length for queue of messages + /** + * The main thread + * @param args command line arguments + */ public static void main(String args[]) { ChatServer cs = new ChatServer(); cs.run(args); @@ -30,7 +32,7 @@ public class ChatServer extends Chat { */ public void run(String args[]) { try { - address = args.length > 0 ? InetAddress.getLocalHost() : InetAddress.getLocalHost(); + address = args.length > 0 ? InetAddress.getByName(args[0]) : InetAddress.getLocalHost(); port = args.length > 1 ? Integer.parseInt(args[1]) : 3400; if(port < 1024) { throw new SCPException("Using a port number 1023 or lower may interrupt system operations"); @@ -41,9 +43,9 @@ public class ChatServer extends Chat { System.out.println("Started server"); hostConnection(welcomeMessage); } catch(SCPException scpe) { - System.err.println(scpe.getMessage()); + System.err.println("Error: " + scpe.getMessage()); } catch(IOException ioe) { - System.err.println(ioe.getMessage()); + System.err.println("Error: " + ioe.getMessage()); } } /** @@ -72,8 +74,10 @@ public class ChatServer extends Chat { out.println(scp.message(address.getHostAddress(), port, message)); System.out.print(String.format("%s is typing...", username)); recievedMessage = recieveMessage(); + System.out.println(); if(recievedMessage == "DISCONNECT") { out.println(scp.acknowledge()); + System.out.println("Client disconnected"); disconnect = true; break; } @@ -84,6 +88,7 @@ public class ChatServer extends Chat { out.println(scp.disconnect()); if(recieveMessage().compareTo("ACKNOWLEDGE") == 0) { disconnect = true; + System.out.println("Successfully disconnected from Client"); break; } else { throw new SCPException("Client did not acknowledge disconnect"); @@ -127,7 +132,7 @@ public class ChatServer extends Chat { packet += inLine + "\n"; } try { - result = scp.parseConnect(packet); + result = scp.parseConnect(packet, address.getHostAddress(), port); } catch(TimeDiffException tde) { reject(tde.getTimeDiff()); } @@ -145,7 +150,7 @@ public class ChatServer extends Chat { * @param username user specified name */ private void scpAccept() { - out.println(scp.accept(username, "127.0.0.1", 3400)); + out.println(scp.accept(username, address.getHostAddress(), port)); } /** * Check if the client has been acknowledged by the server @@ -155,7 +160,7 @@ public class ChatServer extends Chat { while((inLine = in.readLine()).compareTo("SCP END") != 0) { packet += inLine; } - boolean result = scp.parseAcknowledge(packet); + boolean result = scp.parseAcknowledge(packet, address.getHostAddress(), port, username); if(result) { return true; } else { diff --git a/SCP.java b/SCP.java @@ -8,11 +8,14 @@ import java.io.IOException; * * @author Cody Lewis * @since 2018-08-10 - * TODO Add all detail checks to the parsing */ public class SCP { // Packet generating methods /** + * Default constructor + */ + public SCP() {} + /** * Generate the scp connect packet * @param username username of the sender * @param address the server address @@ -94,7 +97,8 @@ public class SCP { /** * Parse a SCP connect packet * @param packet the connect packet - * @return A Result object containing final status and corresponding data + * @param address the caller's ip address + * @return The client's username */ public String parseConnect(String packet, String address, int port) throws TimeDiffException, SCPException, IOException { String username = ""; @@ -109,7 +113,17 @@ public class SCP { } firstLine = false; } - if(line.indexOf("REQUESTCREATED") > -1) { + if(line.indexOf("SERVERADDRESS") > -1) { + if(line.indexOf(address) == -1) { + sstream.close(); + throw new SCPException("SERVERADDRESS " + address, line); + } + } else if(line.indexOf("SERVERPORT") > -1) { + if(line.indexOf(String.format("%d", port)) == -1) { + sstream.close(); + throw new SCPException("SERVERPORT " + port, line); + } + } else if(line.indexOf("REQUESTCREATED") > -1) { int requestTime = Integer.parseInt(line.substring(line.indexOf(" ") + 1)); int timeDiff = findTimeDiff(requestTime); if(timeDiff > 5) { @@ -131,13 +145,64 @@ public class SCP { private int findTimeDiff(int otherTime) { return Math.abs((int)Instant.now().getEpochSecond() - otherTime); } + /** + * Parse a SCP acknowledge packet + * @param packet a SCP packet + * @return true on successful parse else false + */ public boolean parseAcknowledge(String packet) { if (packet.indexOf("SCP ACKNOWLEDGE") > -1) { return true; } return false; } - public boolean parseAccept(String packet, String username) throws SCPException, IOException { + /** + * Parse an extended acknowledge packet + * @param packet a SCP packet + * @param address the server ip address + * @param port the server's port + * @param username the client's username + * @return true on successful parse + */ + public boolean parseAcknowledge(String packet, String address, int port, String username) throws SCPException, IOException { + BufferedReader sstream = new BufferedReader(new StringReader(packet)); + boolean firstLine = true; + String line; + while((line = sstream.readLine()) != null) { + if(firstLine) { + if(line.indexOf("SCP ACKNOWLEDGE") < 0) { + sstream.close(); + throw new SCPException("SCP ACKNOWLEDGE", line); + } + firstLine = false; + } + if(line.indexOf("SERVERADDRESS") > -1) { + if(line.indexOf(address) == -1) { + sstream.close(); + throw new SCPException("SERVERADDRESS " + address, line); + } + } else if(line.indexOf("SERVERPORT") > -1) { + if(line.indexOf(String.format("%d", port)) == -1) { + sstream.close(); + throw new SCPException("SERVERPORT " + port, line); + } + } else if(line.indexOf("USERNAME") > -1) { + if(line.indexOf(username) == -1) { + sstream.close(); + throw new SCPException("USERNAME " + username, line); + } + } + } + sstream.close(); + return true; + } + /** + * Parse a SCP accept packet + * @param packet a SCP packet + * @param username the Client's username + * @return true if successful parse else false + */ + public boolean parseAccept(String packet, String username, String address, int port) throws SCPException, IOException { boolean accept = false; BufferedReader sstream = new BufferedReader(new StringReader(packet)); String line; @@ -151,12 +216,27 @@ public class SCP { } if(line.indexOf("USERNAME") > -1) { if(line.indexOf(username) == -1) { - throw new SCPException(username, line); + throw new SCPException("USERNAME " + username, line); + } + } else if(line.indexOf("CLIENTADDRESS") > -1) { + if(line.indexOf(address) == -1) { + throw new SCPException("CLIENTADDRESS " + address, line); + } + } else if(line.indexOf("CLIENTPORT") > -1) { + if(line.indexOf(String.format("%d", port)) == -1) { + throw new SCPException("CLIENTPORT " + port, line); } } } return true; } + /** + * Parse a SCP message + * @param packet the SCP packet + * @param address the caller's ip address + * @param port the caller's port used for the application + * @return a String of the Message contents + */ public String parseMessage(String packet, String address, int port) throws SCPException, IOException { boolean firstLine = true; BufferedReader sstream = new BufferedReader(new StringReader(packet)); @@ -170,7 +250,7 @@ public class SCP { firstLine = false; } if(line.indexOf("REMOTEADDRESS") > -1) { - if(line.substring(line.indexOf(" ") + 1).indexOf(address) == -1) { + if(line.indexOf(address) == -1) { throw new SCPException("REMOTEADDRESS " + address, line); } } else if(line.indexOf("REMOTEPORT") > -1) { @@ -184,6 +264,11 @@ public class SCP { } return message; } + /** + * Parse a SCP Disconnect + * @param packet a SCP packet + * @return true if successful parse else false + */ public boolean parseDisconnect(String packet) { if (packet.indexOf("SCP DISCONNECT") > -1) { return true;