수색…


비고

SelectionKey셀렉터채널 간에 서로 다른 선택 가능한 연산과 정보를 정의합니다. 특히 첨부 파일 을 사용하여 연결 관련 정보를 저장할 수 있습니다.

OP_READ 처리는 간단합니다. 그러나 OP_WRITE 처리 할 때는주의해야합니다. 대부분의 경우 데이터가 소켓에 기록되어 이벤트가 계속 실행됩니다. 데이터를 쓰기 전에 OP_WRITE 를 등록해야합니다 ( 해당 대답 참조).

또한, OP_CONNECT 채널이 연결되면 취소 (물론,이 연결되어 있기 때문에. 참조해야 SO에 대한 답변을). 따라서 finishConnect()OP_CONNECT 제거가 성공했습니다.

선택기를 사용하여 이벤트를 기다림 (예 : OP_CONNECT)

NIO는 Java 1.4에 출연하여 "채널"이라는 개념을 도입했습니다.이 개념은 일반 I / O보다 빠르다고합니다. 네트워크와 마찬가지로 SelectableChannel 은 채널의 여러 상태를 모니터링 할 수 있으므로 가장 흥미 롭습니다. C select() 시스템 호출과 비슷한 방식으로 작동합니다. 특정 유형의 이벤트가 발생할 때 깨어납니다.

  • 수신 된 연결 ( OP_ACCEPT )
  • 연결 실현 됨 ( OP_CONNECT )
  • 읽기 FIFO ( OP_READ )에서 사용 가능한 데이터
  • 데이터를 FIFO ( OP_WRITE ) 쓰기로 푸시 할 수 있음

그것은 (읽기 / 쓰기 / ...)의 I / O를 I / O (뭔가 읽을 수 / 작성 / ...) 소켓을 감지하고 수행 사이에 분리 할 수 있습니다. 특히 모든 I / O 감지는 다중 소켓 (클라이언트)에 대해 단일 스레드에서 수행 할 수 있으며 I / O 수행은 스레드 풀 또는 다른 곳에서 처리 할 수 ​​있습니다. 따라서 응용 프로그램이 연결된 클라이언트 수에 맞게 쉽게 확장 할 수 있습니다.

다음 예제는 기본 사항을 보여줍니다.

  1. Selector 만들기
  2. SocketChannel 만들기
  3. Selector SocketChannel 등록
  4. 이벤트를 감지하기 위해 Selector 로 루프하기
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");

다음 결과를 얻을 수 있습니다 :

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
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow