7

我正在编写一些 java TCP/IP 网络代码(客户端-服务器),其中我必须处理发送比接收快得多的场景,从而在一端阻止发送操作。(因为发送和接收缓冲区已满)。为了设计我的代码,我想先尝试一下这些情况,看看客户端和服务器在不同负载下的行为。但是我无法适当地设置参数来实现这种背压。我尝试将值设置Socket.setSendBufferSize(int size)Socket.setReceiveBufferSize(int size)较小的值 - 希望很快就会填满,但我可以看到发送操作完成,而无需等待客户端消耗已经写入的足够数据。(这意味着小的发送和接收缓冲区大小没有影响)

我采取的另一种方法是使用 Netty 和 set ServerBootstrap.setOption("child.sendBufferSize", 256);,但即使这样也没多大用处。谁能帮我理解我做错了什么/

4

2 回答 2

4

我认为Channel.setReadable是你需要的。setReadable 告诉 netty 临时暂停从缓冲区中的系统套接字读取数据,当缓冲区已满时,另一端将不得不等待。

于 2012-04-04T17:24:07.097 回答
4

缓冲区的最小大小取决于操作系统,通常约为 8 KB。

public static void main(String... args) throws IOException, InterruptedException {
    ServerSocketChannel ssc = ServerSocketChannel.open();
    ssc.bind(new InetSocketAddress(0)); // open on a random port
    InetSocketAddress remote = new InetSocketAddress("localhost", ssc.socket().getLocalPort());
    SocketChannel sc = SocketChannel.open(remote);
    configure(sc);
    SocketChannel accept = ssc.accept();
    configure(accept);

    ByteBuffer bb = ByteBuffer.allocateDirect(16 * 1024 * 1024);
    // write as much as you can
    while (sc.write(bb) > 0)
        Thread.sleep(1);
    System.out.println("The socket write wrote " + bb.position() + " bytes.");
}

private static void configure(SocketChannel socketChannel) throws IOException {
    socketChannel.configureBlocking(false);
    socketChannel.socket().setSendBufferSize(8);
    socketChannel.socket().setReceiveBufferSize(8);
}

在我的机器上打印

The socket write wrote 32768 bytes.

这是发送和接收缓冲区的总和,但我怀疑它们都是 16 KB

于 2012-04-04T17:24:37.753 回答