Java NIO select()반환하지 않고 선택한 키는데,그 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/204186

  •  03-07-2019
  •  | 
  •  

문제

에서 작성 테스트 코드는 선택합니다.select()반환 할 수 있습니다 수 없는 선택입니다.selectedKeys()를 포함하는 모든 키는 과정이다.에서 이런 일이 일어나는 루프 등록할 때에는 동의()ed 채널

SelectionKey.OP_READ | SelectionKey.OP_CONNECT

으로 운영합니다.

에 따라 문서를 선택,()반환해야 합니다면:

1)가 있는 채널 행동될 수 있습니다.

2)당신은 당신이 명시적으로 호출기를 선택하세요.wakeup()-키이 선택됩니다.

3)당신은 명시적으로 스레드가 있습니다.인터럽트()스레드하 선택(다)-키이 선택됩니다.

면 아무 키 select()내에 있어야 합니다 경우(2)and(3).그러나 나의 코드가 호출하지 wakeup()또는 인터럽트()를 시작하는 이러한 반환합니다.

으로 모든 아이디어이 행동의 원인이 무엇?

도움이 되었습니까?

해결책

짧은 답변 : 제거하십시오 OP_CONNECT 허용 된 연결에 관심이있는 작업 목록에서 허용 된 연결이 이미 연결되어 있습니다.

나는 문제를 재현 할 수 있었는데, 이것은 당신에게 일어나는 일이 될 수 있습니다.

import java.net.*;
import java.nio.channels.*;


public class MyNioServer {
  public static void main(String[] params) throws Exception {
    final ServerSocketChannel serverChannel = ServerSocketChannel.open();
    serverChannel.configureBlocking(true);
    serverChannel.socket().bind(new InetSocketAddress("localhost", 12345));
    System.out.println("Listening for incoming connections");
    final SocketChannel clientChannel = serverChannel.accept();
    System.out.println("Accepted connection: " + clientChannel);


    final Selector selector = Selector.open();
    clientChannel.configureBlocking(false);
    final SelectionKey clientKey = clientChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
    System.out.println("Selecting...");
    System.out.println(selector.select());
    System.out.println(selector.selectedKeys().size());
    System.out.println(clientKey.readyOps());
  }
}

위의 서버가 연결을 수신 한 후 첫 번째 select() 연결에서는 차단하지 않고 종료되며 준비된 작업이있는 키가 없습니다. 나는 왜 Java가 이런 식으로 행동하는지 모르겠지만, 많은 사람들 이이 행동에 물린 것 같습니다.

결과는 Windows XP의 Sun의 JVM 1.5.0_06과 Linux 2.6의 Sun의 JVM 1.5.0_05 및 1.4.2_04에서 동일합니다.

다른 팁

그 이유는 OP_CONNECTOP_WRITE 은 동일한 것을 후드,그래서 당신은 결코에 등록시(ditto OP_ACCEPTOP_READ고),당신은 등록 OP_CONNECT 에서 모든 채널은 이미 연결되어 있는,그것이 이 경우에는,가 받아들여집니다.

OP_WRITE 은 거의 항상 준비하는 경우를 제외하고 소켓을 보낼 버퍼 e 커널은 전체,그래서 당신이해야만 등록에 대한 후에 당신을 얻을 제 길이 작성합니다.그래서 등록하여 이미 연결되어 있는 채널 OP_CONNECT, 당신이 정말 등록 OP_WRITE, 는 준비가 되어 있었고,그렇게 select() 가 트리거됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top