java.nio.channels.ClosedChannelException

lak*_*hmi 13 java

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

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

use*_*421 11

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

您的代码有几个问题.

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

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

第三,关闭频道会取消密钥.您不需要通过取消来关注每一个关闭.

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

我继续对这个帖子中其他地方的声明感到惊讶,感到好笑和困惑,在某些情况下"源代码是不真实的".


小智 1

您需要修复/保护引发此异常的代码。ClosedChannelException是...

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

(如Java 6 API中所述)

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