98 lines
2.9 KiB
Java
98 lines
2.9 KiB
Java
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<SelectionKey> keys = selector.selectedKeys();
|
|
Iterator<SelectionKey> 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|