java.nio.channels.ClosedChannelException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2801087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:59:17  来源:igfitidea点击:

java.nio.channels.ClosedChannelException

java

提问by lakshmi

How can i solve this problem. I got following error:

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

java.nio.channels.ClosedChannelException

java.nio.channels.ClosedChannelException

This is coding:

这是编码:

 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);
            }
        }
    }
}

回答by Piotr Pachalko

You need to fix/secure code that is throwing this exception. ClosedChannelExceptionis ...

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

... thrown when an attempt is made to invoke or complete an I/O operation upon channel that is closed, or at least closed to that operation. That this exception is thrown does not necessarily imply that the channel is completely closed. A socket channel whose write half has been shut down, for example, may still be open for reading

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

(as described in Java 6 API)

(如Java 6 API 中所述

But really, you would need to provide us code snipped and stack trace in order to get more detailed help.

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

回答by user207421

You have closed the channel and are still trying to use it.

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

There are several issues with your code.

您的代码有几个问题。

First, your test for EOS is faulty. Remove the limit() == 0test. That doesn't indicate EOS, it just indicates a zero length read, which can happen in non-blocking mode at any time. It doesn't mean the peer has closed his end of the connection, and it doesn't mean you should close your end.

首先,你对EOS的测试有问题。删除limit() == 0测试。这并不表示 EOS,它只是表示零长度读取,这可能随时在非阻塞模式下发生。这并不意味着对方已经关闭了他的连接端,也不意味着你应该关闭你的端。

Second, closing a channel closes the socket as well. You should close the channel only, not the socket.

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

Third, closing a channel cancels the key. You don't need to follow every close with a cancel.

第三,关闭通道会取消密钥。您不需要在每次关闭后都取消。

You may also have failed to check whether a ready key is valid in the select loop before using it, e.g. for reading.

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

I continue to be amazed, and amused, and bemused, by the claim elsewhere in this thread that 'source code is untrue' under some circumstances.

我继续感到惊讶、好笑和困惑,因为在此线程中的其他地方声称在某些情况下“源代码是不真实的”。