2010-06-27 3 views
2

클라이언트가 보낸 데이터를 읽는 TCP 서버를 쓰려고합니다. 나는 후속 데이터를 읽을 수 있도록 읽기 후에 클라이언트 연결을 열린 상태로 유지하려고합니다. Java 선택기 select()는 항상 마지막 읽기 키를 반환합니다.

내가 실행하고 코드

은 다음과 같습니다 :

while(true) { 
     try { 
      int keysSelected = selector.select(); 

      System.out.println("keysSelected = " + keysSelected); 
      if (keysSelected < 1) { 
       continue;      
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
      break; 
     } 


     Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator(); 

     while(keyIterator.hasNext()) { 
      SelectionKey key = keyIterator.next(); 
      keyIterator.remove(); 

      if (key.isAcceptable()) { 
       processAcceptRequest(selector, key); 
      } else if (key.isReadable()) { 
       processQueryRequest(key); 
      } 
     } 
    } 

내가 경험하고 문제는 그 어떤 클라이언트가 연결 전에, 선택기 블록 선택 호출. 첫 번째 클라이언트가 서버에 연결하여 데이터를 쓰고 나면 읽을 데이터가 없어도 OP_READ 키를 계속 선택하십시오. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 읽기에 대한

코드는 다음과 같습니다

private void processQueryRequest(SelectionKey key) { 
    ByteBuffer byteBuffer = ByteBuffer.allocate(32); 

    SocketChannel clientChannel = (SocketChannel) key.channel(); 

    try { 
     byteBuffer.clear(); 

     while(clientChannel.read(byteBuffer) > 0) { 
      byteBuffer.flip(); 

      Charset charset = Charset.forName("UTF-8"); 
      CharBuffer charBuffer = charset.decode(byteBuffer); 

      System.out.println(charBuffer.toString()); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

감사 브라이언

답변

0

당신이 flip()를 호출하고 당신이 얻을 데이터를 처리 후에는 compact()를 호출해야합니다. 당신은 절대 버퍼를 채우고 있기 때문에, read()은 0을 반환하므로, select() 루프로 돌아가고 있지만 소켓 수신 버퍼에는 아직 보류중인 데이터가 남아 있습니다.

+0

불행히도 이것은 문제를 해결하지 못하는 것 같습니다. 읽기 결과가 항상 -1이지만 읽기에 대한 키가 항상 리턴됩니다. – Brian

+0

이것은 EOS를 의미하므로 채널을 폐쇄해야합니다. – EJP

관련 문제