import java.io.*; import java.net.*; import java.util.*; public class pongServerThread extends Thread { private pongIdentity myID; private Socket clientSocket = null; public pongServerThread(pongIdentity myID, Socket socket) { this.myID = myID; clientSocket = socket; } public void run() { // Handle connection between the pongClient & the masterServer. Socket serverSocket = null; ObjectInputStream serverIn = null; ObjectOutputStream serverOut = null; ObjectInputStream clientIn = null; ObjectOutputStream clientOut = null; // First, (re)establish connection to the masterServer. try { serverSocket = new Socket(Pong.MASTERHOST, Pong.MASTERPORT); serverOut = new ObjectOutputStream(serverSocket.getOutputStream()); serverIn = new ObjectInputStream(serverSocket.getInputStream()); } catch (UnknownHostException e) { System.err.println("pongServerThread: Host unknown : " + e.getMessage()); System.exit(1); } catch (IOException e) { System.err.println("pongServerThread: IO exception : " + e.getMessage()); System.exit(1); } // Next, set up the proper connections for client communication. try { clientOut = new ObjectOutputStream(clientSocket.getOutputStream()); clientIn = new ObjectInputStream(clientSocket.getInputStream()); } catch (UnknownHostException e) { System.err.println("pongServerThread: Host unknown : " + e.getMessage()); System.exit(1); } catch (IOException e) { System.err.println("pongServerThread: IO exception : " + e.getMessage()); System.exit(1); } // // Ready to handle pongClient <--> pongServer protocol! // while (true) { int clientCommand = readResponse(clientIn); if (clientCommand == Pong.CLIENT_READ_FAILED) { return; } switch (clientCommand) { case Pong.CLIENT_LIST: // // Get list from masterServer & send it back to the pongClient. // sendCommand(Pong.SERVER_LIST, serverOut); sendObject(myID, serverOut); Hashtable serverList = null; Object serverObject = null; try { serverObject = serverIn.readObject(); } catch (IOException e) { sendCommand(Pong.CLIENT_NAK, clientOut); return; } catch (ClassNotFoundException e) { sendCommand(Pong.CLIENT_NAK, clientOut); return; } // // See if this is an Integer or a Hashtable. // if (serverObject instanceof Integer) { sendCommand(Pong.CLIENT_NAK, clientOut); System.err.println("pongServerThread: not logged in anymore -- going away!"); pongServer.listening = false; return; } else if (serverObject instanceof Hashtable) { serverList = (Hashtable) serverObject; sendObject(serverList, clientOut); } break; case Pong.CLIENT_PING: // // Send back an ACK to the client (no masterServer involvement). // sendCommand(Pong.CLIENT_ACK, clientOut); break; case Pong.SERVER_PING: // ping another pongServer for this pongClient // // Send back an ACK to the client (no masterServer involvement). // pongIdentity serverID = getPongID(clientIn); if (serverID == null) { sendCommand(Pong.CLIENT_NAK, clientOut); return; } if (pingServer(serverID)) { sendCommand(Pong.CLIENT_ACK, clientOut); } else { sendCommand(Pong.CLIENT_NAK, clientOut); } break; default: return; // bail out if an illegal command } } } static int readResponse(ObjectInputStream serialIn) { int response = 0; try { response = ((Integer) serialIn.readObject()).intValue(); } catch (IOException e) { return Pong.CLIENT_READ_FAILED; } catch (ClassNotFoundException e) { return Pong.CLIENT_READ_FAILED; } return response; } static void sendCommand(int command, ObjectOutputStream serialOut) { try { serialOut.writeObject(new Integer(command)); } catch (IOException e) { return; } } static void sendObject(Object object, ObjectOutputStream serialOut) { try { serialOut.writeObject(object); } catch (IOException e) { return; } } static boolean pingServer(pongIdentity userID) { // Ping the pongServer identified by userID (using CLIENT_PING). Socket serverSocket = null; ObjectInputStream serialIn = null; ObjectOutputStream serialOut = null; try { serverSocket = new Socket(userID.myIP, userID.myPort); serialOut = new ObjectOutputStream(serverSocket.getOutputStream()); serialIn = new ObjectInputStream(serverSocket.getInputStream()); } catch (UnknownHostException e) { System.err.println("pongServerThread: pingServer: UnknownHostException: " + e.getMessage()); return false; } catch (IOException e) { System.err.println("pongServerThread: pingServer: IOexception: " + e.getMessage()); return false; } // Ping the (other) pongServer sendCommand(Pong.CLIENT_PING, serialOut); int response = readResponse(serialIn); if (response != Pong.CLIENT_ACK) return false; try { serialIn.close(); serialOut.close(); serverSocket.close(); } catch (IOException e) { System.err.println("pongServerThread: pingServer: close: " + e.getMessage()); return false; } return true; } static pongIdentity getPongID(ObjectInputStream serialIn) { pongIdentity pongID; try { pongID = (pongIdentity) serialIn.readObject(); } catch (IOException e) { return null; } catch (ClassNotFoundException e) { return null; } return pongID; } }