Skip to content
Snippets Groups Projects
Commit de0b74b1 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Made human entry & display of IP addresses using unsigned values

parent 51c3da83
No related branches found
No related tags found
No related merge requests found
*.html
ASSIGNMENTS = $(wildcard *.md)
ASSIGNMENT_HTML = $(ASSIGNMENTS:%.md=%.html)
all: $(ASSIGNMENT_HTML)
%.html: %.md
pandoc -o $@ $<
sed "s/’/'/g" $@ | sed "s/‘/'/g" | sed 's/”/"/g' | sed 's/“/"/g' > temp
mv temp $@
...@@ -127,7 +127,7 @@ feel for how the program works. ...@@ -127,7 +127,7 @@ feel for how the program works.
chatters chatters
- When launching SocketChat, both chatters should select the option to be - When launching SocketChat, both chatters should select the option to be
the client the client
- IP address: `-127.93.-91.26` <!--`129.93.165.26`-->, Port: `361NN`, - IP address: <!--`-127.93.-91.26`--> `129.93.165.26`, Port: `361NN`,
where *NN* is your team number where *NN* is your team number
- The two chatters alternate turns sending Strings to each other over the - The two chatters alternate turns sending Strings to each other over the
socket socket
......
...@@ -21,6 +21,15 @@ public class Chat { ...@@ -21,6 +21,15 @@ public class Chat {
socket = null; socket = null;
} }
/**
* Provides a test hook to test that the program terminates.
*
* @param exitCode the code passed to the shell indicating (ab)normal termination
*/
protected void exit(int exitCode) {
System.exit(exitCode);
}
/** /**
* Overrides the system's default Locale. * Overrides the system's default Locale.
* *
...@@ -90,9 +99,10 @@ public class Chat { ...@@ -90,9 +99,10 @@ public class Chat {
*/ */
private Socket connectAsServer(Scanner userInput) throws IOException { private Socket connectAsServer(Scanner userInput) throws IOException {
byte[] address = InetAddress.getLocalHost().getAddress(); byte[] address = InetAddress.getLocalHost().getAddress();
short[] humanReadableAddress = signedToUnsignedAddress(address);
// "Host address: ..." // "Host address: ..."
System.out.println(MessageFormat.format(bundle.getString("connection.info.hostAddress.0.1.2.3"), System.out.println(MessageFormat.format(bundle.getString("connection.info.hostAddress.0.1.2.3"),
address[0], address[1], address[2], address[3])); humanReadableAddress[0], humanReadableAddress[1], humanReadableAddress[2], humanReadableAddress[3]));
int port; int port;
ServerSocket serverSocket; ServerSocket serverSocket;
do { do {
...@@ -119,9 +129,10 @@ public class Chat { ...@@ -119,9 +129,10 @@ public class Chat {
*/ */
private Socket connectAsClient(Scanner userInput) throws IOException { private Socket connectAsClient(Scanner userInput) throws IOException {
byte[] address = getRemoteHostAddress(userInput); byte[] address = getRemoteHostAddress(userInput);
short[] humanReadableAddress = signedToUnsignedAddress(address);
// "Enter port host is opening at ..." // "Enter port host is opening at ..."
String prompt = MessageFormat.format(bundle.getString("connection.prompt.getHostPort.0.1.2.3"), String prompt = MessageFormat.format(bundle.getString("connection.prompt.getHostPort.0.1.2.3"),
address[0], address[1], address[2], address[3]); humanReadableAddress[0], humanReadableAddress[1], humanReadableAddress[2], humanReadableAddress[3]);
int port = getPort(prompt, userInput); int port = getPort(prompt, userInput);
Socket socket = null; Socket socket = null;
int attemptCount = 0; int attemptCount = 0;
...@@ -161,7 +172,7 @@ public class Chat { ...@@ -161,7 +172,7 @@ public class Chat {
private byte[] getRemoteHostAddress(Scanner userInput) { private byte[] getRemoteHostAddress(Scanner userInput) {
// This assumes IPv4. Probably a good assumption. // This assumes IPv4. Probably a good assumption.
boolean haveGoodAddress = false; boolean haveGoodAddress = false;
byte[] address = new byte[4]; short[] address = new short[4];
while (!haveGoodAddress) { while (!haveGoodAddress) {
// "Enter IP address of host <##.##.##.##>:" // "Enter IP address of host <##.##.##.##>:"
System.out.print(bundle.getString("connection.prompt.getHostAddress") + " "); System.out.print(bundle.getString("connection.prompt.getHostAddress") + " ");
...@@ -170,7 +181,7 @@ public class Chat { ...@@ -170,7 +181,7 @@ public class Chat {
String[] tokens = addressString.split("\\."); String[] tokens = addressString.split("\\.");
if (tokens.length == 4) { if (tokens.length == 4) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
address[i] = Byte.parseByte(tokens[i]); address[i] = Short.parseShort(tokens[i]);
} }
haveGoodAddress = true; haveGoodAddress = true;
} else { } else {
...@@ -179,9 +190,10 @@ public class Chat { ...@@ -179,9 +190,10 @@ public class Chat {
addressString)); addressString));
haveGoodAddress = false; haveGoodAddress = false;
} }
} catch (NumberFormatException nfException) { } catch (NumberFormatException ignored) {
// "The IP address should be exactly as reported to the host user." // "The IP address should be exactly as reported to the host user."
System.out.println(bundle.getString("connection.error.badNumberInAddress")); System.out.println(bundle.getString("connection.error.badNumberInAddress"));
/*
String message = nfException.getMessage(); String message = nfException.getMessage();
// "Value out of range. Value" // "Value out of range. Value"
if (message.startsWith(bundle.getString("exception.numberFormat.startOfValueOutOfRangeMessage"))) { if (message.startsWith(bundle.getString("exception.numberFormat.startOfValueOutOfRangeMessage"))) {
...@@ -193,10 +205,11 @@ public class Chat { ...@@ -193,10 +205,11 @@ public class Chat {
"connection.error.userAttemptedUnsignedByte.0.1"), value, value - 256)); "connection.error.userAttemptedUnsignedByte.0.1"), value, value - 256));
} }
} }
*/
haveGoodAddress = false; haveGoodAddress = false;
} }
} }
return address; return unsignedToSignedAddress(address);
} }
/** /**
...@@ -234,6 +247,46 @@ public class Chat { ...@@ -234,6 +247,46 @@ public class Chat {
return port; return port;
} }
/**
* Utility function necessary because Java does not have unsigned integer types. Converts from the signed bytes
* that Java uses for IP address fields and mimics unsigned values that humans are accustomed to.
*
* @param signedAddress IP address fields in the range -128..127
* @return IP address fields in the range 0..255
*/
private short[] signedToUnsignedAddress(byte[] signedAddress) {
short offset = -2 * Byte.MIN_VALUE;
short[] unsignedAddress = new short[signedAddress.length];
for (int i = 0; i < signedAddress.length; i++) {
if (signedAddress[i] >= 0) {
unsignedAddress[i] = signedAddress[i];
} else {
unsignedAddress[i] = (short) (offset + signedAddress[i]);
}
}
return unsignedAddress;
}
/**
* Utility function necessary because Java does not have unsigned integer types. Converts from the unsigned values
* that humans are accustomed to and converts them to signed bytes that Java uses for IP address fields.
*
* @param unsignedAddress IP address fields in the range 0..255
* @return IP address fields in the range -128..127
*/
private byte[] unsignedToSignedAddress(short[] unsignedAddress) {
short offset = -2 * Byte.MIN_VALUE;
byte[] signedAddress = new byte[unsignedAddress.length];
for (int i = 0; i < unsignedAddress.length; i++) {
if (unsignedAddress[i] <= Byte.MAX_VALUE) {
signedAddress[i] = (byte) unsignedAddress[i];
} else {
signedAddress[i] = (byte) (unsignedAddress[i] - offset);
}
}
return signedAddress;
}
/* /*
* THESE METHODS PERFORM CHAT AFTER CONNECTION IS SET UP * THESE METHODS PERFORM CHAT AFTER CONNECTION IS SET UP
*/ */
...@@ -363,10 +416,6 @@ public class Chat { ...@@ -363,10 +416,6 @@ public class Chat {
return true; return true;
} }
protected void exit(int exitCode) {
System.exit(exitCode);
}
private String encipher(String plaintext) { private String encipher(String plaintext) {
String ciphertext = plaintext; // Replace this with a call to cipherBehavior.encipher(plaintext) String ciphertext = plaintext; // Replace this with a call to cipherBehavior.encipher(plaintext)
return ciphertext; return ciphertext;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment