java - 是否可以重复从 channel 写入和读取?

标签 java netty

我尝试重复写入和读取 channel ,但在第二次写入尝试时失败,因为在读取第一个响应后 channel 已被 NioWorker 关闭。

我用谷歌搜索了一整天,但没有找到任何线索。如何在同一个 channel 上进行写-读-写-读操作?

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

最佳答案

Netty 不会关闭连接,除非用户关闭它或对等方关闭它。请确保没有引发异常。

关于java - 是否可以重复从 channel 写入和读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10832325/

相关文章:

java - 没有标题的 DialogFragment 缩小对话框宽度

java - 是否可以在 netty 服务器上的两个不同端口上打开两个单独的连接?

ssl - 在 Play Framework 1.2.7 中使用的 Netty 的 SSL 处理程序中处理多个证书

java - (Java) Switch 语句中的全局变量问题

java - AsynchronousFileChannel 写入失败

java - 当我添加 ExecutionHandler 时,netty 服务器似乎被阻止了?

java - 使用 Netty HTTP 客户端重试请求

java - 如何判断当前客户端socket已经关闭并连接到另一台服务器?

frames - 如何让网页在框架中打开?

java - 需要实现两个接口(interface)的泛型