1

チャネルからの書き込みと読み取りを繰り返し試みていますが、最初の応答が読み取られた後に NioWorker によってチャネルが既に閉じられているため、2 回目の書き込み試行で失敗しました。

私は一日中グーグルで検索しましたが、手がかりを見つけることができませんでした. 同じチャネルで書き込み-読み取り-書き込み-読み取り操作を実行するにはどうすればよいですか?

org.jboss.netty.channel.socket.nio.NioWorker ソースコードの一部:

private void processSelectedKeys(Set<SelectionKey> selectedKeys) throws IOException {
    for (Iterator<SelectionKey> i = selectedKeys.iterator(); i.hasNext();) {
        SelectionKey k = i.next();
        i.remove();
        try {
            int readyOps = k.readyOps();
            if ((readyOps & SelectionKey.OP_READ) != 0 || readyOps == 0) {
                if (!read(k)) {
                    // Connection already closed - no need to handle write.
                    continue;
                }
            }
            if ((readyOps & SelectionKey.OP_WRITE) != 0) {
                writeFromSelectorLoop(k);
            }
        } catch (CancelledKeyException e) {
            close(k);
        }

        if (cleanUpCancelledKeys()) {
            break; // break the loop to avoid ConcurrentModificationException
        }
    }
}

private boolean read(SelectionKey k) {
    final SocketChannel ch = (SocketChannel) k.channel();
    final NioSocketChannel channel = (NioSocketChannel) k.attachment();

    final ReceiveBufferSizePredictor predictor =
        channel.getConfig().getReceiveBufferSizePredictor();
    final int predictedRecvBufSize = predictor.nextReceiveBufferSize();

    int ret = 0;
    int readBytes = 0;
    boolean failure = true;

    ByteBuffer bb = recvBufferPool.acquire(predictedRecvBufSize);
    try {
        while ((ret = ch.read(bb)) > 0) {
            readBytes += ret;
            if (!bb.hasRemaining()) {
                break;
            }
        }
        failure = false;
    } catch (ClosedChannelException e) {
        // Can happen, and does not need a user attention.
    } catch (Throwable t) {
        fireExceptionCaught(channel, t);
    }

    if (readBytes > 0) {
        bb.flip();

        final ChannelBufferFactory bufferFactory =
            channel.getConfig().getBufferFactory();
        final ChannelBuffer buffer = bufferFactory.getBuffer(readBytes);
        buffer.setBytes(0, bb);
        buffer.writerIndex(readBytes);

        recvBufferPool.release(bb);

        // Update the predictor.
        predictor.previousReceiveBufferSize(readBytes);

        // Fire the event.
        fireMessageReceived(channel, buffer);
    } else {
        recvBufferPool.release(bb);
    }

    // NioWorker closes the channel, making it impossible to write additional messages.
    if (ret < 0 || failure) {
        k.cancel(); // Some JDK implementations run into an infinite loop without this.
        close(channel, succeededFuture(channel));
        return false;
    }

    return true;
}
4

1 に答える 1

1

Netty は、ユーザーまたはピアが接続を閉じない限り、接続を閉じません。例外が発生していないことを確認してください。

于 2012-05-31T15:05:12.593 に答える