import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.concurrent.CopyOnWriteArrayList; public class ChatClient implements Runnable { static public class Endpoint { Endpoint(String ipport) throws UnknownHostException { String [] parts = ipport.split(":"); if (parts.length == 2) { ipaddress = InetAddress.getByName(parts[0]); port = Integer.parseInt(parts[1]); } } public String toString() { return ipaddress.getHostAddress() + ":" + Integer.toString(port); } InetAddress ipaddress; int port; } public class ChatSession implements Runnable { Endpoint curEndpoint; Socket sock; Scanner recv; PrintWriter send; Thread t; boolean bServ; ChatSession(Socket s, boolean bServ) throws IOException { this.bServ = bServ; sock = s; InetSocketAddress isa = ((InetSocketAddress)s.getRemoteSocketAddress()); curEndpoint = new Endpoint(isa.getHostName() + ":" + isa.getPort()); send = new PrintWriter(sock.getOutputStream()); recv = new Scanner(sock.getInputStream()); t = new Thread(this); t.start(); } Endpoint getEndpoint() { return curEndpoint; } void start() { try { while (true) { String s = recv.nextLine(); System.out.println(s); } } catch (Exception e) { } } void send(String s) throws IOException { send.println(s); send.flush(); } @Override public void run() { try { if (bServ) { List eps = getEndpoints(); eps.remove(curEndpoint.toString()); send(String.join(" ", eps)); curEndpoint.port = Integer.parseInt(recv.nextLine()); } else { String[] clients = recv.nextLine().split(" "); send(Integer.toString(port)); for (String aClient : clients) { Endpoint ec; if (!aClient.isEmpty()) { ec = new Endpoint(aClient); if (!getEndpoints().contains(ec.toString())) { connectTo(ec); } } } } start(); } catch (UnknownHostException e) { } catch (IOException e) { } catch (Exception e) { } } } ChatClient(int port) { this.port = port; } List chatSessions = new CopyOnWriteArrayList(); int port; @Override public void run() { try { listen(port); } catch (IOException e) { } } void listen(int port) throws IOException { ServerSocket ss = new ServerSocket(port); while (true) { chatSessions.add(new ChatSession(ss.accept(), true)); } //ss.close(); } List getEndpoints() { List eps = new ArrayList(); for (ChatSession s : chatSessions) { eps.add(s.getEndpoint().toString()); } return eps; } void connectTo(Endpoint ep) throws IOException { Socket s = new Socket(); s.connect(new InetSocketAddress(ep.ipaddress, ep.port)); chatSessions.add(new ChatSession(s, false)); } public static void main(String [] args) throws IOException { if (args.length >= 1) { ChatClient cc = new ChatClient(Integer.parseInt(args[0])); Thread n = new Thread(cc); n.start(); if (args.length == 2) { Endpoint client = new Endpoint(args[1]); cc.connectTo(client); } BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while (true) { String send = br.readLine(); for (ChatSession s : cc.chatSessions) { s.send(send); } } //n.join(); } } }