java.nio.channels.ClosedChannelException - PullRequest
13 голосов
/ 10 мая 2010

Как я могу решить эту проблему. Я получил следующую ошибку:

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

Ответы [ 2 ]

11 голосов
/ 01 июня 2013

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

Есть несколько проблем с вашим кодом.

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

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

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

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

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

0 голосов
/ 10 мая 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...