import java.io.*; import java.net.*; import java.util.*; /** A simple server that lets clients chat with one another. */ public class ChatServer { public static final int PORT = 5678; /** Program that runs the chat server until killed. */ public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(PORT); // crash if this fails // List of all connections that are listening for messages. List listeners = new ArrayList<>(); // Wait for new connections until the program is killed. while (true) { Socket clientSocket = serverSocket.accept(); // crash if this fails try { // Process this client as a listener or speaker: // * Listeners are recorded in the list above. // * Messages from speakers are echoed to each listener. String line = readLine(clientSocket); if (line.equals("listen")) { listeners.add(clientSocket); } else if (line.startsWith("speak ")) { removeClosed(listeners); // drop those that disconnected for (Socket listenSocket : listeners) writeLine(listenSocket, line.substring(6)); closeSocket(clientSocket); } else { writeLine(clientSocket, "Error: unknown command '" + line + "'"); closeSocket(clientSocket); } } catch (IOException ex) { // This is an error reading from the new connection. Just ignore it. ex.printStackTrace(System.err); closeSocket(clientSocket); } } } /** Reads the first line from the given socket. */ private static String readLine(Socket socket) throws IOException { BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()), 1); return reader.readLine(); } /** Writes the given line to the given socket, ignoring any exception. */ private static void writeLine(Socket socket, String line) { try { Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write(line + "\n"); writer.flush(); } catch (IOException ex) { ex.printStackTrace(System.err); closeSocket(socket); // don't try to write anymore } } /** Closes the given socket, ignoring (but printing) any exception. */ private static void closeSocket(Socket socket) { try { socket.close(); } catch (IOException ex) { ex.printStackTrace(System.err); } } /** Removes all closed sockets from the given list. */ private static void removeClosed(List sockets) { Iterator iter = sockets.iterator(); while (iter.hasNext()) { Socket socket = iter.next(); if (socket.isClosed()) iter.remove(); } } }