import java.util.*; import java.io.*; import java.net.*; class ChatClient { public static void main(String[] args) { if (args.length == 2) { try { int listeningPort = Integer.parseInt(args[0]); Endpoint client = new Endpoint(args[1]); ChatClient program = new ChatClient(listeningPort); ChatServer server = new ChatServer(listeningPort, program); server.start(); // creates a new thread program.connectTo(client); program.run(); } catch (UnknownHostException e) { System.err.println("Unknown host: " + args[0]); } catch (IOException e) { System.err.println("An error happened: " + e.getMessage()); } } } private List sessions; // default value is null private int listeningPort; // default value is 0 public ChatClient(int port) { // better than using synchronized block everywhere.. sessions = Collections.synchronizedList(new LinkedList<>()); listeningPort = port; } public List getSessions() { return sessions; } public void run() { System.out.println("Reading messages..."); Scanner keyboard = new Scanner(System.in); while (true) { String message = keyboard.nextLine(); synchronized (sessions) { for (ChatSession session : sessions) { session.sendMessage(message); } } } } private boolean isAlreadyConnected(Endpoint client) { synchronized (sessions) { for (ChatSession session : sessions) if (session.getEndpoint().equals(client)) return true; return false; } } private void connectTo(Endpoint client) throws IOException { System.out.println("Connecting to " + client); if (isAlreadyConnected(client)) return; else { ChatSession session = new ChatSession(client); String[] clients = session.receiveMessage().split(" "); System.out.println("got clients:" + java.util.Arrays.toString(clients)); session.sendMessage(listeningPort + ""); // int -> String conversion synchronized (sessions) { sessions.add(session); } session.start(); // here we spawn a new thread for (String aClient : clients) { if (!aClient.isEmpty()) { try { Endpoint e = new Endpoint(aClient); connectTo(e); } catch (UnknownHostException e) { // ignore incorrect address } } } } } }