3 Stimmen

Wann wird der Java-Nio-Selektor beim select()-Aufruf entsperrt?

Ich lerne gerade das NIO-Paket. Ich beziehe mich auf das NioServer Beispiel von aquí . Der Selektorfaden in NioServer.java Blöcke auf

this.selector.select(); 
Iterator<SelectionKey> selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
    SelectionKey key = selectedKeys.next();
    selectedKeys.remove();
    if (!key.isValid()) {
        continue;
    }

    if (key.isAcceptable()) {
        this.accept(key);
    } else if (key.isReadable()) {
        this.read(key);
    } else if (key.isWritable()) {
        this.write(key);
    }

Wenn ein entfernter Client eine Verbindung herstellt, this.accept(key) aufgerufen und in dieser Methode die Zinsen interestOps auf Read geändert und der Selektor geweckt. Ist es das, was den Selektor veranlasst, diesen Kanal auszuwählen? Wir signalisieren also auf diese Weise, dass der Kanal ausgewählt werden soll?

Nehmen wir nun an, dass beim Schreiben in eine Steckdose der Kanalselektor durch Änderung des Interesse, dass der Kanal zum Schreiben bereit ist. Aber nehmen wir an, dass der Schreibvorgang nicht abgeschlossen werden konnte, weil der Socket-Puffer voll war, wie im Code gezeigt, dann ändern wir das Interesse nicht und lassen es so, wie es ist, nur zum Schreiben. Wann wird dann der Selektor diesen Kanal auswählen?

3voto

SimonJ Punkte 20636
  1. this.accept(key) ruft auf. serverSocketChannel.accept() die eine neu Socket-Kanal für die Kommunikation mit dem Kunden. Es ist este Kanal, der mit dem Selektor für "Lese"-Vorgänge registriert ist, d.h. der Selektor hat jetzt zwei Anmeldungen:

    • der ursprüngliche ServerSocketChannel, mit OP_ACCEPT
    • den SocketChannel für den neuen Client, mit OP_READ
  2. Wenn ein Schreibvorgang nicht abgeschlossen werden kann, weil der Puffer voll ist, bleibt der entsprechende SocketChannel mit OP_WRITE registriert. Sobald der Client einige Daten vom anderen Ende liest, wird der Kanal wieder ausgewählt, so dass wir die verbleibenden Daten schreiben können, bevor das Interesse wieder auf OP_READ gesetzt wird.

1voto

user207421 Punkte 297318

OP_WRITE wird ausgelöst, wenn im Socket-Sendepuffer noch Platz ist.

Die einzige Möglichkeit, OP_WRITE zu verwenden, besteht darin, ein Write()-Ergebnis der Länge Null zu erhalten. Die meiste Zeit ist noch Platz, so dass OP_WRITE weiterhin ausgelöst wird. Das ist nicht erwünscht, daher wird OP_WRITE normalerweise nicht für einen Kanal registriert: nur dann, wenn das Ergebnis des Schreibvorgangs Null ist; und die Registrierung wird aufgehoben, wenn der Schreibvorgang durch erneute Auslösung nach einem OP_WRITE abgeschlossen ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X