2010-06-27 48 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

你需要調用compact()你打電話flip()和處理你得到數據後。你永遠不會這樣做,所以你填充緩衝區,所以read()返回零,所以你回到select()循環,但仍然有套接字接收緩衝區中的數據。

+0

不幸的是,這似乎並沒有解決問題。即使讀取的結果始終爲-1,讀取的關鍵仍總是返回。 – Brian 2010-06-28 20:40:54

+0

這意味着EOS,所以你應該已經關閉了頻道。 – EJP 2010-06-29 01:57:59