import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; public class chat { private ServerSocket serverSocket; // initialized in ctor private Map> members = new HashMap<>(); public static void main(String[] args) { try { new chat().acceptloop(); } catch (IOException e) { e.printStackTrace(); } } public chat() throws IOException { this.serverSocket = new ServerSocket(5999); } private void acceptloop() throws IOException { while (true) { Socket c = serverSocket.accept(); new Thread(new connection(this, c)).start(); } } public synchronized void connect(String user, Consumer callback) { for (Map.Entry> e : members.entrySet()) { try { callback.accept(e.getKey() + " arrived"); } catch (Exception ex) { disconnect(e.getKey()); } } members.put(user, callback); announce(user + " arrived"); } public synchronized void disconnect(String user) { members.remove(user); announce(user + " left"); } public synchronized void speak(String user, String text) { announce(user + " says '" + text + "'"); } private void announce(String s) { for (Map.Entry> e : members.entrySet()) { try { e.getValue().accept(s); } catch (Exception ex) { disconnect(e.getKey()); } } } private static class connection implements Runnable { private chat room; private Socket c; private static int userCount = 0; private String user = "user" + (userCount++); public connection(chat room, Socket c) { this.room = room; this.c = c; } @Override public void run() { try { BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream())); PrintWriter out = new PrintWriter(new OutputStreamWriter(c.getOutputStream())); room.connect(user, (String s) -> { out.println(s); out.flush(); }); while (true) { String line = in.readLine(); if (line == null) break; room.speak(user, line); } } catch (IOException e) { e.printStackTrace(); } finally { room.disconnect(user); } } } }