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

Ответ 1

Вы закрыли канал и все еще пытаетесь его использовать.

В коде есть несколько проблем.

Во-первых, ваш тест на EOS неисправен. Удалите тест limit() == 0. Это не указывает на EOS, это просто указывает на чтение нулевой длины, которое может произойти в неблокирующем режиме в любое время. Это не означает, что сверстник закрыл свой конец соединения, и это не значит, что вы должны закрыть свой конец.

Во-вторых, закрытие канала также закрывает сокет. Вы должны закрыть канал, а не сокет.

В-третьих, закрытие канала отменяет ключ. Вам не нужно следить за каждым закрытием с отменой.

Возможно, вам также не удалось проверить, действительно ли ключ готовности в цикле выбора, прежде чем использовать его, например. для чтения.

Я по-прежнему удивляюсь, удивляюсь и смущен выражением в другом месте этого потока, что "исходный код не соответствует действительности" при некоторых обстоятельствах.

Ответ 2

Вам нужно исправить/защитить код, который выбрасывает это исключение. ClosedChannelException...

... бросается, когда делается попытка вызвать или завершить операции ввода-вывода по каналу, который закрыты или, по крайней мере, закрыты для этого операция. Это исключение брошенное не обязательно означает, что канал полностью закрыт. канал сокета, чья половина записи имеет например, может быть закрыт быть открытым для чтения

(как описано в API Java 6)

Но на самом деле вам нужно будет предоставить нам код, который был бы отключен, и трассировку стека, чтобы получить более подробную помощь.