java.nio.channels.ClosedChannelException

我怎么解决这个问题。 我收到了以下错误:

java.nio.channels.ClosedChannelException

这是编码:

  public void run() { try { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(512); int i1 = socketChannel.read(buffer); if (buffer.limit() == 0 || i1 == -1) { Socket s = null; try { s = socketChannel.socket(); s.close(); key.cancel(); } catch (IOException ie) { if (UnitDataServer.isLog) { log.error("Error closing socket " + s + ": " + ie); } } } else { buffer.flip(); if (UnitDataServer.isLog) { log.info(" Recvd Message from Unit : " + buffer.array()); } byte byteArray[] = buffer.array(); log.info("Byte Array length :" + byteArray.length); hexString = new StringBuffer(); for (int i = 0; i < i1 /* byteArray.length */; i++) { String hex = Integer.toHexString(0xFF & byteArray[i]); if (hex.length() == 1) { // could use a for loop, but we're only dealing with a // single byte hexString.append('0'); } hexString.append(hex); } hexString.trimToSize(); log.info("Hex String :" + hexString); Communicator.dataReceive(new DataReceive( socketChannel, hexString.toString(), dst)); } } catch (Exception e) { if (UnitDataServer.isLog) { // log.error(e); } try { socketChannel.socket().close(); key.cancel(); } catch (IOException ex) { if (UnitDataServer.isLog) { log.error(ex); } } } } 

您已关闭频道并仍在尝试使用它。

您的代码有几个问题。

首先,您对EOS的测试是错误的。 删除limit() == 0测试。 这并不表示EOS,它只是指示零长度读取,这可以在任何时间以非阻塞模式发生。 这并不意味着同伴关闭了他的连接结束,并不意味着你应该关闭你的结束。

其次,关闭通道也会关闭套接字。 您应该只关闭通道,而不是套接字。

第三,关闭频道取消密钥。 您不需要通过取消来关注每一次结束。

您可能还没有在使用之前检查就绪键是否在选择循环中有效,例如用于读取。

我仍然对这个post中其他地方的声明感到惊讶,感到好笑和困惑,在某些情况下“源代码是不真实的”。

您需要修复/保护引发此exception的代码。 ClosedChannelException是……

…当尝试在关闭或至少关闭该操作的通道上调用或完成I / O操作时抛出… 抛出此exception并不一定意味着通道完全关闭。 例如,其写半部分已关闭的套接字通道仍可以打开以供读取

(如Java 6 API中所述 )

但实际上,您需要为我们提供代码剪切和堆栈跟踪,以获得更详细的帮助。