与nio有些麻烦

时间:2012-04-05 22:31:41

标签: java nio

我决定使用java nio制作我的UDPclient和UDPserver。 但我不明白几件事。 这是代码

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”(我自己的方法)时,我不明白如何处理我的事件。

2 个答案:

答案 0 :(得分:1)

  1. 您传递给select的值是超时而非通道数。

  2. 你需要做

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

  3. 不使用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);
        }
    

答案 1 :(得分:0)

  

如果我在控制台中写一些内容,那么key.isWritable中的事件就会出现   发生?

没有。将发生的唯一事件是您在选择器中注册的通道。您尚未注册任何与控制台有关的频道,但您不能,因为只有网络频道是SelectableChannels,因此您必须推理通过选择器调出来自控制台的事件。

  

如果服务器发送了一些事件,那么会发生isReadable吗?

  

我不明白如何处理我的事件,例如用户   写“GETL”或“REGR”(我自己的方法)。

我也不是。我甚至不理解这个问题。您将从选择器中获得的唯一事件是它在您注册的频道上定义的事件。