Simulate back pressure in a TCP message

I am writing some kind of java TCP / IP network code (client-server) in which I have to deal with scenarios where the deliveries are much faster than the recipients, thereby blocking send operations at one end. (because the send and recv buffers are full). To develop my code, I first wanted to first understand these situations and see how the client and servers behave under different loads. But I cannot correctly configure the parameters to provide this backpressure. I tried to set Socket.setSendBufferSize(int size)it Socket.setReceiveBufferSize(int size)to small values ​​- hoping that this would be replenished soon, but I see that the send operation is completed, without waiting for the client to consume enough already recorded data. (this means that the size of the send and return buffer has no effect)

Another approach I took is to use Netty and install ServerBootstrap.setOption("child.sendBufferSize", 256);, but even this is not very useful. Can someone help me understand what I'm doing wrong /

+5
source share
2 answers

Buffers have a limited OS size of a minimum size, often around 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);
}

prints on my machine

The socket write wrote 32768 bytes.

This is the sum of the send and receive buffers, but I suspect they are 16 KB

+3
source

I think that Channel.setReadableis what you need. setReadable tell netty a temporary pause to read data from the system socket in the buffer, when the buffer is full, the other end will have to wait.

+4
source

All Articles