2011-05-14 2 views
3

NIO 패키지를 배우고 있습니다. NioServer 예제를 here에서 참조합니다. select() 호출시 java nio 선택기가 차단을 해제 할 때

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); 
    } 

원격 클라이언트가 연결

NioServer.java 블록 선택기 스레드, this.accept(key)가 호출되고,이 방법에 관심 interestOps 읽기로 변경하고 선택을 깨우고있다. 이 무엇입니까 선택기가이 채널을 선택하게합니까? 그래서 우리는 채널이 선택되도록 이러한 방식으로 신호를 보내고 있습니까?

채널에 쓸 준비가되었다는 관심을 변경하여 소켓 채널 선택기에 대한 쓰기가 신호되었다고 가정 해 보겠습니다. 그러나 코드 에서처럼 소켓 버퍼가 꽉 찼기 때문에 쓰기가 완료되지 않았다고 가정하면 관심을 변경하지 않고 쓰기 전용 상태로 유지합니다. 그러면 선택기에서이 채널을 언제 선택합니까? 클라이언트와의 통신을위한 새로운 소켓 채널을 반환

+1

무한대로 차단하지 말고 대신 과부하 된 select (long timeout) 메서드를 사용하십시오. – Schildmeijer

답변

3
  1. this.accept(key) 전화 serverSocketChannel.accept().

    • 원래 ServerSocketChannel을 함께 OP_ACCEPT
    • 새로운 클라이언트에 대한 SocketChannel에와, 상기 선택은 지금 등록을 가지고 즉 그것은 작업을 "읽기"에 대한 선택기에 등록이 채널 입니다 OP_READ
  2. 버퍼가 가득 차서 쓰기가 완료되지 않으면 해당 SocketChannel은 OP_WRITE로 등록 된 상태로 유지됩니다. 클라이언트가 다른 쪽 끝에서 일부 데이터를 읽으면 채널이 다시 선택되므로 OP_READ에 관심 분야 세트를 뒤집기 전에 나머지 데이터를 쓸 수 있습니다.

1

OP_WRITE는 소켓 송신 버퍼에 공간이있을 때 트리거됩니다.

길이가 0 인 write() 결과를 얻는 NB가 OP_WRITE를 사용하는 유일한 경우입니다. 대부분의 시간에는 여유 공간이 있으므로 OP_WRITE가 계속 트리거됩니다. 당신은 이것을 원하지 않으므로 일반적으로 채널에 대해 OP_WRITE를 등록하지 않아도됩니다 : 단지 쓰기에서 0을 반환했을 때만; OP_WRITE 이후에 다시 트리거 됨으로써 쓰기가 완료 될 때 등록을 취소합니다.

관련 문제