Sök…


Anmärkningar

SelectionKey definierar de olika valbara operationerna och informationen mellan dess väljare och kanal . Speciellt kan bilagan användas för att lagra anslutningsrelaterad information.

Att OP_READ är ganska rak. Man bör dock vara försiktig när man hanterar OP_WRITE : för det mesta kan data skrivas till uttag så att händelsen fortsätter att skjutas. Se till att registrera OP_WRITE endast innan du vill skriva data (se svaret ).

OP_CONNECT bör också avbrytas när kanalen har anslutit (eftersom den är ansluten. Se detta och det svar på SO). Därför OP_CONNECT borttagningen efter finishConnect() .

Använd väljaren för att vänta på händelser (exempel med OP_CONNECT)

NIO dök upp i Java 1.4 och introducerade konceptet "Kanaler", som ska vara snabbare än vanlig I / O. Nätverksmässigt är SelectableChannel det mest intressanta eftersom det gör det möjligt att övervaka olika tillstånd i kanalen. Det fungerar på samma sätt som C select() -systemet: vi vaknar upp när vissa typer av händelser inträffar:

  • anslutning mottagen ( OP_ACCEPT )
  • anslutning realiserad ( OP_CONNECT )
  • data tillgängliga i lästa FIFO ( OP_READ )
  • data kan drivas för att skriva FIFO ( OP_WRITE )

Det gör det möjligt att skilja mellan detektering av socket I / O (något kan läsas / skrivas / ...) och utföra I / O (läs / skriva / ...). Speciellt kan all I / O-detektion göras i en enda tråd för flera socklar (klienter), medan utföra I / O kan hanteras i en trådpool eller någon annanstans. Det gör att en applikation lätt kan skalas till antalet anslutna klienter.

Följande exempel visar grunderna:

  1. Skapa en Selector
  2. Skapa en SocketChannel
  3. Registrera SocketChannel till Selector
  4. Slinga med Selector att upptäcka händelser
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");

Skulle ge följande utgång:

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow