Java Language
NIO - Vernetzung
Suche…
Bemerkungen
SelectionKey
definiert die verschiedenen auswählbaren Operationen und Informationen zwischen Selector und Channel . Insbesondere kann der Anhang verwendet werden, um verbindungsbezogene Informationen zu speichern.
Der Umgang mit OP_READ
ist ziemlich unkompliziert. Beim Umgang mit OP_WRITE
jedoch Vorsicht OP_WRITE
: In der OP_WRITE
können Daten in Sockets geschrieben werden, sodass das Ereignis weiterhin OP_WRITE
wird. OP_WRITE
Sie sicher, dass OP_WRITE
nur OP_WRITE
registrieren, bevor Sie Daten schreiben möchten (siehe Antwort ).
Auch OP_CONNECT
soll abgebrochen werden , sobald der Kanal verbunden ist (weil, na ja, es verbunden ist. Sehen Sie dies und dass Antworten auf SO). Daraus ergibt sich die OP_CONNECT
Entfernung nach finishConnect()
erfolgreich war.
Mit Selector auf Ereignisse warten (Beispiel mit OP_CONNECT)
NIO erschien in Java 1.4 und führte das Konzept der "Channels" ein, die schneller als normale E / A sein sollen. Aus SelectableChannel
des Netzwerks ist der SelectableChannel
der interessanteste, da er die Überwachung verschiedener Status des Kanals ermöglicht. Es funktioniert auf ähnliche Weise wie der Aufruf von C select()
: Wir werden geweckt, wenn bestimmte Ereignistypen auftreten:
- Verbindung empfangen (
OP_ACCEPT
) - Verbindung hergestellt (
OP_CONNECT
) - Daten im Lese-FIFO verfügbar (
OP_READ
) - Daten können zum Schreiben des
OP_WRITE
(OP_WRITE
)OP_WRITE
Es ermöglicht die Trennung zwischen Buchse Erkennung I / O (etwas gelesen / geschrieben / ...) und der Durchführung des E / A (Lesen / Schreiben / ...). Insbesondere kann die gesamte E / A-Erkennung in einem einzigen Thread für mehrere Sockets (Clients) durchgeführt werden, während E / A-Vorgänge in einem Thread-Pool oder an einem anderen Ort ausgeführt werden können. Dadurch kann eine Anwendung problemlos auf die Anzahl der verbundenen Clients skaliert werden.
Das folgende Beispiel zeigt die Grundlagen:
- Erstellen Sie eine
Selector
- Erstellen Sie einen
SocketChannel
- Registrieren Sie den
SocketChannel
imSelector
- Schleife mit dem
Selector
, um Ereignisse zu erkennen
Selector sel = Selector.open(); // Create the Selector
SocketChannel sc = SocketChannel.open(); // Create a SocketChannel
sc.configureBlocking(false); // ... non blocking
sc.setOption(StandardSocketOptions.SO_KEEPALIVE, true); // ... set some options
// Register the Channel to the Selector for wake-up on CONNECT event and use some description as an attachement
sc.register(sel, SelectionKey.OP_CONNECT, "Connection to google.com"); // Returns a SelectionKey: the association between the SocketChannel and the Selector
System.out.println("Initiating connection");
if (sc.connect(new InetSocketAddress("www.google.com", 80)))
System.out.println("Connected"); // Connected right-away: nothing else to do
else {
boolean exit = false;
while (!exit) {
if (sel.select(100) == 0) // Did something happen on some registered Channels during the last 100ms?
continue; // No, wait some more
// Something happened...
Set<SelectionKey> keys = sel.selectedKeys(); // List of SelectionKeys on which some registered operation was triggered
for (SelectionKey k : keys) {
System.out.println("Checking "+k.attachment());
if (k.isConnectable()) { // CONNECT event
System.out.print("Connected through select() on "+k.channel()+" -> ");
if (sc.finishConnect()) { // Finish connection process
System.out.println("done!");
k.interestOps(k.interestOps() & ~SelectionKey.OP_CONNECT); // We are already connected: remove interest in CONNECT event
exit = true;
} else
System.out.println("unfinished...");
}
// TODO: else if (k.isReadable()) { ...
}
keys.clear(); // Have to clear the selected keys set once processed!
}
}
System.out.print("Disconnecting ... ");
sc.shutdownOutput(); // Initiate graceful disconnection
// TODO: emtpy receive buffer
sc.close();
System.out.println("done");
Würde folgende Ausgabe ergeben:
Initiating connection
Checking Connection to google.com
Connected through 'select()' on java.nio.channels.SocketChannel[connection-pending remote=www.google.com/216.58.208.228:80] -> done!
Disconnecting ... done