package chatmulti; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import csc4509.ReadMessageStatus; import csc4509.Message; public class ChatServerMain { boolean debug = false; public static void main(String[] argv) { int ports[]; ReadMessageStatus rms = null; Selector selector; HashMap<SelectionKey,Message> hm = new HashMap<SelectionKey,Message>(); try { selector = Selector.open(); } catch (IOException e1) { e1.printStackTrace(); return; } if (argv.length == 0) { System.out.println("usage: java ChatServerMain <portClient> [nomMachineServeur]"); return; } else if (argv.length == 2) { /* On se connecte à un serveur */ Message m = new Message(1); try { SocketChannel serversc = SocketChannel.open(new InetSocketAddress(InetAddress.getByName(argv[1]), Integer.parseInt(argv[0])+100)); serversc.configureBlocking(false); m.setSc(serversc); hm.put(serversc.register(selector, SelectionKey.OP_READ), m); } catch (NumberFormatException e) { e.printStackTrace(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } ports = new int[2]; ports[0] = Integer.parseInt(argv[0]); ports[1] = ports[0] + 100; try { for (int i=0; i<ports.length; ++i) { ServerSocketChannel ssc = ServerSocketChannel.open(); /* Socket non bloquant */ ssc.configureBlocking(false); ServerSocket ss = ssc.socket(); InetSocketAddress rcvAddress = new InetSocketAddress( ports[i] ); ss.bind( rcvAddress ); /* Initalisation du Selector */ ssc.register(selector, SelectionKey.OP_ACCEPT); } /* Socket en écoute */ while (true) { /* Init selector */ selector.select(); Set<SelectionKey> readyKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = readyKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = (SelectionKey) iterator.next(); if (key.isValid() && key.isAcceptable()) { /* Accepter une nouvelle connexion */ ServerSocketChannel ssc = (ServerSocketChannel)key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); /* Nouveau message */ Message mess = new Message(1); mess.setSc(sc); /* Ajout de cette connexion au selector */ SelectionKey newKey = sc.register( selector, SelectionKey.OP_READ); /* Sauvegarde du mesasge dans hashmap */ hm.put(newKey, mess); iterator.remove(); System.out.println("Nouveau client:" + mess.getHost()); } else if (key.isValid() && key.isReadable()) { SocketChannel sc = (SocketChannel)key.channel(); Message mess = hm.get(key); if (mess == null) { rms = ReadMessageStatus.ChannelClosed; } else { rms = mess.readMessage(sc); } if (rms == ReadMessageStatus.ReadDataCompleted) { /* Le message est reçu complètement */ String s = null; try { s = (String) mess.getData(); } catch (IOException e) { e.printStackTrace(); } System.out.println("Message reçu (" + mess.getHost() +") :" + s); /* Il faut l'envoyer a tous les autres*/ for (Iterator<Message> i = hm.values().iterator() ; i.hasNext() ;){ Message m = i.next(); if (!m.equals(mess)) { /* On envoie pas au client son propre message */ m.setMessage(1, s); m.write(m.getSc()); } } //System.out.println(s); } else if (rms == ReadMessageStatus.ChannelClosed) { System.out.println("Client supprimé"); key.cancel(); hm.remove(key); } iterator.remove(); } else if (!key.isValid()) { key.cancel(); hm.remove(key); iterator.remove(); } } } } catch (SocketException se) { se.printStackTrace(); return; } catch (UnknownHostException ue) { ue.printStackTrace(); return; } catch (IOException ie) { ie.printStackTrace(); return; } } }