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
Branches
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.
chatters
- When launching SocketChat, both chatters should select the option to be
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
- The two chatters alternate turns sending Strings to each other over the
socket
......
......@@ -21,6 +21,15 @@ public class Chat {
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.
*
......@@ -90,9 +99,10 @@ public class Chat {
*/
private Socket connectAsServer(Scanner userInput) throws IOException {
byte[] address = InetAddress.getLocalHost().getAddress();
short[] humanReadableAddress = signedToUnsignedAddress(address);
// "Host address: ..."
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;
ServerSocket serverSocket;
do {
......@@ -119,9 +129,10 @@ public class Chat {
*/
private Socket connectAsClient(Scanner userInput) throws IOException {
byte[] address = getRemoteHostAddress(userInput);
short[] humanReadableAddress = signedToUnsignedAddress(address);
// "Enter port host is opening at ..."
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);
Socket socket = null;
int attemptCount = 0;
......@@ -161,7 +172,7 @@ public class Chat {
private byte[] getRemoteHostAddress(Scanner userInput) {
// This assumes IPv4. Probably a good assumption.
boolean haveGoodAddress = false;
byte[] address = new byte[4];
short[] address = new short[4];
while (!haveGoodAddress) {
// "Enter IP address of host <##.##.##.##>:"
System.out.print(bundle.getString("connection.prompt.getHostAddress") + " ");
......@@ -170,7 +181,7 @@ public class Chat {
String[] tokens = addressString.split("\\.");
if (tokens.length == 4) {
for (int i = 0; i < 4; i++) {
address[i] = Byte.parseByte(tokens[i]);
address[i] = Short.parseShort(tokens[i]);
}
haveGoodAddress = true;
} else {
......@@ -179,9 +190,10 @@ public class Chat {
addressString));
haveGoodAddress = false;
}
} catch (NumberFormatException nfException) {
} catch (NumberFormatException ignored) {
// "The IP address should be exactly as reported to the host user."
System.out.println(bundle.getString("connection.error.badNumberInAddress"));
/*
String message = nfException.getMessage();
// "Value out of range. Value"
if (message.startsWith(bundle.getString("exception.numberFormat.startOfValueOutOfRangeMessage"))) {
......@@ -193,10 +205,11 @@ public class Chat {
"connection.error.userAttemptedUnsignedByte.0.1"), value, value - 256));
}
}
*/
haveGoodAddress = false;
}
}
return address;
return unsignedToSignedAddress(address);
}
/**
......@@ -234,6 +247,46 @@ public class Chat {
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
*/
......@@ -363,10 +416,6 @@ public class Chat {
return true;
}
protected void exit(int exitCode) {
System.exit(exitCode);
}
private String encipher(String plaintext) {
String ciphertext = plaintext; // Replace this with a call to cipherBehavior.encipher(plaintext)
return ciphertext;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment