Three way handshake implemented client and server side and functioning

Server generates a new Id for connections (Size of connections + 1)
Client now stores an id allocated to it by the server
The id is currently being saved in the clientToServer thread client side

tags: #story[987] #implement
This commit is contained in:
William Muir
2017-07-22 17:44:37 +12:00
parent 3ec930491f
commit 2869d139a3
3 changed files with 88 additions and 26 deletions
@@ -17,12 +17,15 @@ import seng302.server.messages.Message;
*/ */
public class ClientToServerThread implements Runnable { public class ClientToServerThread implements Runnable {
private static final int LOG_LEVEL = 1;
private Thread thread; private Thread thread;
private Integer ourID;
private Socket socket; private Socket socket;
private InputStream is; private InputStream is;
private OutputStream os; private OutputStream os;
private static final int LOG_LEVEL = 1;
private Boolean updateClient = true; private Boolean updateClient = true;
private ByteArrayOutputStream crcBuffer; private ByteArrayOutputStream crcBuffer;
@@ -36,6 +39,16 @@ public class ClientToServerThread implements Runnable {
e.printStackTrace(); e.printStackTrace();
} }
Integer allocatedID = threeWayHandshake();
if (allocatedID != null) {
ourID = allocatedID;
clientLog("Successful handshake. Allocated ID: " + ourID, 1);
} else {
clientLog("Unsuccessful handhsake", 1);
closeSocket();
return;
}
thread = new Thread(this); thread = new Thread(this);
thread.start(); thread.start();
@@ -96,6 +109,33 @@ public class ClientToServerThread implements Runnable {
} }
/**
* Listens for an allocated sourceID and returns it to the server if recieved
* @return the sourceID allocated to us by the server
*/
private Integer threeWayHandshake() {
Integer ourSourceID = null;
while (true) {
try {
ourSourceID = is.read();
} catch (IOException e) {
e.printStackTrace();
}
if (ourSourceID != null) {
try {
os.write(ourSourceID);
return ourSourceID;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
/** /**
* Send the post-start race course information * Send the post-start race course information
*/ */
@@ -121,4 +121,14 @@ public class GameState {
yacht.update(timeInterval); yacht.update(timeInterval);
} }
} }
/**
* Generates a new ID based off the size of current players + 1
* @return a playerID to be allocated to a new connetion
*/
public static Integer getUniquePlayerID() {
// TODO: 22/07/17 wmu16 - This may not be robust enough and may have to be improved on.
return yachts.size() + 1;
}
} }
@@ -47,11 +47,19 @@ public class ServerToClientThread implements Runnable {
} catch (IOException e) { } catch (IOException e) {
System.out.println("IO error in server thread upon grabbing streams"); System.out.println("IO error in server thread upon grabbing streams");
} }
// threeWayHandshake();
GameState.addPlayer(new Player(socket)); //Attempt threeway handshake with connection
Random rand = new Random(); sourceId = GameState.getUniquePlayerID();
sourceId = rand.nextInt(100000); if (threeWayHandshake(sourceId)) {
GameState.addYacht(sourceId, new Yacht("Kappa", "Kap", new GeoPoint(0.0, 0.0), 0.0)); serverLog("Successful handshake. Client allocated id: " + sourceId, 1);
GameState.addYacht(sourceId,
new Yacht("Kappa", "Kap", new GeoPoint(0.0, 0.0), 0.0));
GameState.addPlayer(new Player(socket)); //Is this neccesary???
} else {
serverLog("Unsuccessful handshake. Connection rejected", 1);
closeSocket();
return;
}
thread = new Thread(this); thread = new Thread(this);
thread.start(); thread.start();
@@ -113,7 +121,7 @@ public class ServerToClientThread implements Runnable {
} }
} }
} catch (Exception e) { } catch (Exception e) {
serverLog("ERROR OCCURED, CLOSING SERVER CONNETION: " + socket.getRemoteSocketAddress().toString(), 1); serverLog("ERROR OCCURRED, CLOSING SERVER CONNECTION: " + socket.getRemoteSocketAddress().toString(), 1);
closeSocket(); closeSocket();
return; return;
} }
@@ -132,28 +140,32 @@ public class ServerToClientThread implements Runnable {
* if so, sends a confirmation packet back to that connection * if so, sends a confirmation packet back to that connection
* Creates a player instance with that ID and this thread and adds it to the GameState * Creates a player instance with that ID and this thread and adds it to the GameState
* If not, close the socket and end the threads execution * If not, close the socket and end the threads execution
* @param id the id to try and assign to the connection
* @return A boolean indicating if it was a successful handshake
*/ */
private void threeWayHandshake() { private Boolean threeWayHandshake(Integer id) {
// // TODO: 13/07/17 Finish using AC35 Integer confirmationID = null;
// Integer playerID = GameState.getUniquePlayerID(); Integer identificationAttempt = 0;
// Integer confirmationID = null; while (!userIdentified) {
// Integer identificationAttempt = 0 try {
// while (!userIdentified) { os.write(id); //Send out new ID looking for echo
// os.write(playerID); //Send out new ID looking for echo confirmationID = is.read();
// confirmationID = is.read(); } catch (IOException e) {
// if (playerID == idConfirmation) { //ID is echoed back. Connection is a client e.printStackTrace();
// os.write( some determined confirmation message ); //Confirm to client
// GameState.addPlayer(new Player(playerID, this)); //Create a player in game state for client
// userIdentified = true;
// } else if (identificationAttempt > MAX_ID_ATTEMPTS) { //No response. not a client. tidy up and go home.
// closeSocket();
// return;
// }
// identificationAttempt++;
// }
} }
public void closeSocket() { if (id.equals(confirmationID)) { //ID is echoed back. Connection is a client
return true;
} else if (identificationAttempt > MAX_ID_ATTEMPTS) { //No response. not a client. tidy up and go home.
return false;
}
identificationAttempt++;
}
return true;
}
private void closeSocket() {
try { try {
socket.close(); socket.close();
} catch (IOException e) { } catch (IOException e) {