est un exemple de serveur chargen j'ai trouvé dans le livre que je lisais:Comment écrire une seule fois ou "sur une commande" en utilisant des sockets NIO? Ce
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;
import java.io.IOException;
public class ChargenServer {
public static int DEFAULT_PORT = 19;
public static void main(String[] args) {
int port;
try {
port = Integer.parseInt(args[0]);
}
catch (Exception ex) {
port = DEFAULT_PORT;
}
System.out.println("Listening for connections on port " + port);
byte[] rotation = new byte[95*2];
for (byte i = ' '; i <= '~'; i++) {
rotation[i-' '] = i;
rotation[i+95-' '] = i;
}
ServerSocketChannel serverChannel;
Selector selector;
try {
serverChannel = ServerSocketChannel.open();
ServerSocket ss = serverChannel.socket();
InetSocketAddress address = new InetSocketAddress(port);
ss.bind(address);
serverChannel.configureBlocking(false);
selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
catch (IOException ex) {
ex.printStackTrace();
return;
}
while (true) {
try {
selector.select();
}
catch (IOException ex) {
ex.printStackTrace();
break;
}
Set readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
iterator.remove();
try {
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel client = server.accept();
System.out.println("Accepted connection from " + client);
client.configureBlocking(false);
SelectionKey key2 = client.register(selector, SelectionKey.OP_WRITE);
ByteBuffer buffer = ByteBuffer.allocate(74);
buffer.put(rotation, 0, 72);
buffer.put((byte) '\r');
buffer.put((byte) '\n');
buffer.flip();
key2.attach(buffer);
}
else if (key.isWritable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = (ByteBuffer) key.attachment();
if (!buffer.hasRemaining()) {
// Refill the buffer with the next line
buffer.rewind();
// Get the old first character
int first = buffer.get();
// Get ready to change the data in the buffer
buffer.rewind();
// Find the new first characters position in rotation
int position = first - ' ' + 1;
// copy the data from rotation into the buffer
buffer.put(rotation, position, 72);
// Store a line break at the end of the buffer
buffer.put((byte) '\r');
buffer.put((byte) '\n');
// Prepare the buffer for writing
buffer.flip();
}
client.write(buffer);
}
}
catch (IOException ex) {
key.cancel();
try {
key.channel().close();
}
catch (IOException cex) {}
}
}
}
}
}
Une fois que le client est connecté au serveur, il continue à envoyer un flux de caractères au client et ne s'arrête pas.
Je suis curieux si je veux envoyer le tampon une fois et toujours garder le serveur connecté au client. Que devrais-je faire?
Donc l'utilisation de 'OP_WRITE' est de toujours écrire en boucle? – user963241
Je ne vous comprends pas. L'utilisation de OP_WRITE est de vous dire quand le socket est devenu inscriptible après l'une des rares occasions où il ne l'est pas, comme signalé par un retour à zéro de 'write()'. – EJP
Je vois. Si normal 'write()' échoue alors je devrais enregistrer OP_WRITE et le laisser continuer à écrire jusqu'à ce qu'il réussisse puis désenregistrer dans 'key.isWriteable()'? – user963241