2011-10-06 2 views
1

나는 이걸 알아 내는데 어려움을 겪고있다.SocketChannel.read() blocks 무기한

synchronized public void becomesReadable(SelectionKey key) throws IOException { 
    ByteBuffer temporaryBuffer = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE); 
    temporaryBuffer.position(0); 
    int read = -1; 
    try { 
     read = channel.read(temporaryBuffer); 
    } catch (IOException e) { 
     prefixLogger.debug("Trace:", e); 
     close(); 
    } 
    ... 
} 

을 그리고 그 핸들러 함수가 지금이라고 유일한 지점이다 : 읽기 위해

if (selector.select(1000) <= 0) { 
     return; 
    } 
    Set<SelectionKey> selectionKeys = selector.selectedKeys(); 
    for (SelectionKey key : selectionKeys) { 
     try { 
      SocketEventHandler handler = (SocketEventHandler) key.attachment(); 
      if (key.isValid() && key.isAcceptable()) { 
       handler.becomesAcceptable(key); 
      } 
      if (key.isValid() && key.isReadable()) { 
       handler.becomesReadable(key); 
      } 

      if (key.isValid() && key.isWritable()) { 
       handler.becomesWritable(key); 
      } 

      if (key.isValid() && key.isConnectable()) { 
       handler.becomesConnectable(key); 
      } 
     } catch (IOException e) { 
      key.cancel(); 
     } 
    } 
    selector.selectedKeys().clear(); 

다음 처리기 코드 : 나는 다음과 같은 코드가 있습니다. 따라서 만약 내가 becomeReadable() 함수에 들어가면 채널은 읽을 수있는 상태이지만 아직 돌아 오지 않고 read() 블록을 호출합니다. 내가 놓친 것이 있습니까?

답변

0

코드에 channel.configureBlocking(false) (으)로 전화 했습니까?

여기서 어떤 채널을 사용하고 있는지 알기는 어렵지만 원래는 SocketChannel이 차단 모드로 생성 된 것 같습니다.

+0

채널이 비 차단으로 구성되어 있으며 잠시 동안 조용하게 작동합니다. 잠시 후 문제가 나타납니다. socketChannel의 상태를 확인하고 원래 게시물을 업데이트합니다 :-) – cdecker

+1

그는 완료해야합니다. 그렇지 않으면 등록 또는 선택할 수 없었습니다. – EJP

1

왜 becomeReadable() 메서드가 동기화되어 있는지 궁금합니다. NIO를 사용하면 동기화가 줄어 듭니다.

또한 IOException을 로깅하지 않는 이유와 채널을 닫지 않고 키를 취소하는 이유가 궁금합니다. 그래서 당신이 모르는 I/O 예외가 무엇인지 궁금합니다.

또한 버퍼를 할당하는 작업은 매우 비쌉니다. 모든 읽기 작업을 수행 할 때마다 그렇게해서는 안되며, 채널에 할당 된 SocketEventHandler 인스턴스에서 세션 상태를 가져야합니다.

+0

정말 좋은 점은 최대한 빨리 해결할 것입니다. – cdecker