// RUN METHOD public void run() { for (int x = 0; x <= 3; x++) { selected[x] = false; questions[x] = ""; } // Create new lists for the clients and threads if (clientSocketList == null || !clientSocketList.isEmpty()) { clientSocketList = new Vector<ClientConnection>(); } if (clientThreadList == null || !clientThreadList.isEmpty()) { clientThreadList = new Vector<Thread>(); } // Now we're ready to go isRunning = true; stopPressed = false; // Server initialization parent.updateStatusBox("SERVER ONLINE"); parent.setStatus(new Color(32, 160, 32), "ONLINE"); parent.setButtonEnabled(parent.STOP_BUTTON, true); Socket clientSocket = null; // SERVER CONNECTION LOOP AND CLIENT THREAD GENERATION while (!stopPressed) { try { // Create a new socket and wait for a client connection parent.updateStatusBox("Listening for clients on port: " + String.valueOf(port)); serverSocket = new ServerSocket(port); clientSocket = serverSocket.accept(); // Once a connection is established, we pass it off to clientConnected, which creates a new // thread // to manage this client clientConnected(clientSocket); } catch (IOException e) { // No need to implement anything here -- cleanup is taken care of outside the loop // TODO: Move cleanup to a FINALLY block parent.updateStatusBox(e.getMessage()); } finally { try { if (serverSocket != null) { serverSocket.close(); } } catch (IOException e) { parent.updateStatusBox(e.getMessage()); } } } // We're responsible adults...once we leave the server connection loop, we need to clean up // (close all // connections) before we can officially stop the server. parent.updateStatusBox("Stopping server..."); // Instead of locking clientSocketList inside of a huge synchronized block, just make a copy of // it // This is a good idea because as clients disconnect, they will be asking to remove // themselves from // the clientSocketList, and we don't want them to wait Vector<ClientConnection> snapshot = new Vector<ClientConnection>(); snapshot.addAll(clientSocketList); Iterator<ClientConnection> clientIterator = snapshot.iterator(); ClientConnection clientConnection; // This loop iterates through all of the currently connected clients and disconnects them while (clientIterator.hasNext()) { clientConnection = clientIterator.next(); parent.updateStatusBox("Stopping client from ServerRunnable Loop"); disconnectClient(clientConnection); } snapshot.clear(); // Once we've cleaned up, we let the user know that the server is down and re-enable the Start // Server button parent.updateStatusBox("\nSERVER SHUTDOWN COMPLETE"); parent.setStatus(Color.RED, "OFFLINE"); isRunning = false; parent.setButtonEnabled(parent.GO_BUTTON, true); }