2012-04-05 98 views
0

我決定用java nio製作我的UDPclient和UDPserver。 但我不明白幾件事情。 下面是代碼nio的一些麻煩

try { 
    DatagramChannel channel = DatagramChannel.open(); 
    channel.configureBlocking(false); 
    channel.connect(remote); 
    //monitoring 
    Selector selector = Selector.open(); 
    //read write keys 
    channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);  
    ByteBuffer buffer = ByteBuffer.allocate(1024*64);//number of bytes for channel 
    while (true) { 
    selector.select(60000);//number of channels I think 
    Set readyKeys = selector.selectedKeys(); 
    if (readyKeys.isEmpty()) { 
     break; 
    } 
    else { 
     Iterator iterator = readyKeys.iterator(); 
     while (iterator.hasNext()) { 
     SelectionKey key = (SelectionKey) iterator.next(); 
     iterator.remove(); 
     if (key.isReadable()) { 
      //read from buffer 
      channel.read(buffer); 
     } 
     if (key.isWritable()) { 
      //write to buffer 
      channel.write(buffer); 
     } 
     } 
    } 
    } 
} 
catch (IOException ex) { 
    System.err.println(ex); 
} 

如果我寫在控制檯東西key.isWritable的事件發生?如果服務器發送事件isReadable將發生? 而我不明白如何處理我的事件,例如用戶編寫「GETL」或「REGR」(我自己的方法)。

回答

1
  1. 您傳遞給select的值是超時而不是通道數。

  2. 你需要做的

    DatagramChannel channelFromKey = (DatagramChannel) key.channel();

不使用channel

我不明白你自己的事件是什麼意思。當選擇該鍵時,從通道讀取數據標記。

Iterator iterator = readyKeys.iterator(); 
while (iterator.hasNext()) { 
    SelectionKey key = (SelectionKey) iterator.next(); 
    iterator.remove(); 
    if (key.isReadable()) { 
     DatagramChannel channelFromKey = 
      (DatagramChannel) key.channel(); 
     buffer.clear(); 
     // This is a DatagramChannel receive a datagram as a whole 
     channelFromKey.receive(buffer); 
    } 
+0

但如果不僅從套接字讀取,而且從BufferedReader.readline讀取呢? – 2012-04-05 23:00:09

+0

您未使用流媒體套接字。您正在使用數據報套接字。這意味着你的接收將是數據報包。 ReadLine對此沒有多大意義。實際上,BufferedReader在任何套接字上都沒有多少意義。 – 2012-04-05 23:18:52

+0

使用頻道的想法是,它不僅可以讀取fron插座,還可以讀取鍵盤上的數據......所以即使使用頻道也不可能...... – 2012-04-05 23:39:32

0

如果我寫在控制檯東西key.isWritable事件會發生 ?

不會。唯一會發生的事件發生在您向選擇器註冊的通道上。您尚未註冊任何與控制檯相關的頻道,但您不能,因爲只有網絡頻道是SelectableChannel,所以您必須有理由期望來自控制檯的事件通過選擇器啓動。

如果服務器發送事件isReadable會發生?

是的。

而我不明白如何處理我的事件時,例如用戶 寫「GETL」或「REGR」(我自己的方法)。

我也不明白這個問題。您將從選擇器獲得的唯一事件是它在您註冊的頻道上定義的事件。