package fr.istic.nio; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Set; import java.util.Iterator; public class PingPong { private static final int PORT_NUMBER = 6969; // Phrase ACCEPT private static void accept(SocketChannel sc, SelectionKey key) throws IOException { sc.configureBlocking(false); ByteBuffer buffer = ByteBuffer.allocate(64); sc.register(key.selector(), SelectionKey.OP_READ, buffer); } // Phrase READ private static void read(SelectionKey key) throws IOException { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) key.attachment(); if (client.read(buffer) < 0) { client.close(); return; } else { buffer.flip(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes, 0, buffer.remaining()); String message = new String(bytes); String[] splited = message.split("\\s+"); if (splited[0].equals("PING") && splited.length == 2) { // On récupère le nombre pour bien le traiter sinon // message.remplace est plus vite que ça mais c'est ptet un PING STRING int number = Integer.parseInt(splited[1]); buffer.clear(); // C'est plus facile quand on a déjà le nombre ici que le transferer // dans la partie write, donc on le fait buffer write ici String pong = "PONG " + number; buffer.put(pong.getBytes()); // flip pour envoyer le buffer buffer.flip(); key.interestOps(SelectionKey.OP_WRITE); } } } // Phrase WRITE private static void write(SelectionKey key) throws IOException { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) key.attachment(); client.write(buffer); buffer.clear(); key.interestOps(SelectionKey.OP_READ); } public static void main(String[] args) throws IOException { ServerSocketChannel server = ServerSocketChannel.open(); server.socket().bind(new InetSocketAddress(PORT_NUMBER)); server.socket().setReuseAddress(true); // Mode non bloquant server.configureBlocking(false); // Création du sélecteur Selector selector = Selector.open(); server.register(selector, SelectionKey.OP_ACCEPT); while (true) { int channelcount = selector.select(); if (channelcount > 0) { Set keys = selector.selectedKeys(); Iterator iterator = keys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); if (!key.isValid()) { continue; } if (key.isAcceptable()) { SocketChannel client = server.accept(); accept(client, key); } else if (key.isReadable()) { read(key); } else if (key.isWritable()) { write(key); } } } } } }