Il y a une prise, qui me coûte plusieurs heures pour comprendre. Considérez le code suivant:
SocketChannel socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 22));
socket.configureBlocking(false);
Selector selector = Selector.open();
SelectionKey selkey = socket.register(selector, 0);
....
selkey.interestOps(SelectionKey.OP_READ);
selector.select(1000);
System.out.println("Selecting r, return " +
(selector.selectedKeys().contains(selkey) && selkey.isReadable() ? "r" : "") +
(selector.selectedKeys().contains(selkey) && selkey.isWritable() ? "w" : ""));
Il imprime "Sélection r, return w". Il est donc possible que isWritable() soit vrai alors que seul OP_READ est intéressé. Cela se produit si OP_WRITE est inclus dans un appel select() précédent et que select() renvoie 0, ce qui signifie que la touche selkey n'est pas mise à jour.
Le code de preuve complet est ici: https://gist.github.com/wuyongzheng/43cc9dc07e13124663d1. Pour exécuter, vous avez besoin d'un serveur SSH sur le port 22.
C'est une question différente, mais dans quelles circonstances (mise à part la fermeture de la connexion entre isWriteable() et write()) l'écriture peut-elle échouer/être retardée? – tstenner
c'est ce que dit SelectionKey javadoc. – irreputable