commit 0d57f08c912af44e2158b91a081c54e7c4ae4ca8
parent 07e82437a6c70757c817303c7cf2ffe91ef13e9f
Author: Cody Lewis <luxdotsugi@gmail.com>
Date: Tue, 21 Aug 2018 10:07:30 +1000
The program works completely
Diffstat:
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;