title: How correctly close SocketChannel in Java NIO?
body: <p>I have a simple non-blocking server with main loop:</p>
  
  <pre><code>try {
      while (selector.select() &gt; -1) {
  
          // Wait for an event one of the registered channels
  
          // Iterate over the set of keys for which events are available
          Iterator selectedKeys = selector.selectedKeys().iterator();
          while (selectedKeys.hasNext()) {
              SelectionKey key = (SelectionKey) selectedKeys.next();
              selectedKeys.remove();
              try {
                  if (!key.isValid()) {
                      continue;
                  }
  
                  if (key.isConnectable()) {
                      connect(key);
                  }
  
                  // Check what event is available and deal with it
                  if (key.isAcceptable()) {
                      accept(key);
                  }
  
                  if (key.isReadable()) {
                      read(key);
                  }
  
                  if (key.isWritable()) {
                      write(key);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  close(key);
              }
          }
      }
  } catch (Exception e) {
      e.printStackTrace();
  }
  </code></pre>
  
  <p>In read/write section I check if there is something to read/write if not - then I try to close channel:</p>
  
  <pre><code>if (channel.read(attachment.buffer) &lt; 1) 
      close(key);
  </code></pre>
  
  <p>Close method:</p>
  
  <pre><code>private void close(SelectionKey key) throws IOException {
      key.cancel();
      key.channel().close();
  }
  </code></pre>
  
  <p>But during processing this code I get exception in main loop (it is catched but I supposed something wrong) I get this stacktrace:</p>
  
  <pre><code>java.nio.channels.CancelledKeyException
      at sun.nio.ch.SelectionKeyImpl.ensureValid(Unknown Source)
      at sun.nio.ch.SelectionKeyImpl.readyOps(Unknown Source)
      at java.nio.channels.SelectionKey.isWritable(Unknown Source)
  </code></pre>
  
  <p>So it fails on main loop when enter write section, close channel and came back to main loop in 'writable' if section and fails with such exception. Any suggestions?</p>