Simulate back pressure in TCP send

java, netty, tcp

Solution

The buffers have an OS dependent minimium size, this is 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);
}

on my machine prints

The socket write wrote 32768 bytes.

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

Problem

I am writing some java TCP/IP networking code ( client - server ) in which I have to deal with scenarios where the sends are much faster than the receives , thus blocking the send operations at one end. ( because the send and recv buffers fill up ). In order to design my code , I wanted to first play around these kind of situations first and see how the client and servers behave under varying load. But I am not able to set the parameters appropriately for acheiving this back pressure. I tried setting `Socket.setSendBufferSize(int size)` and `Socket.setReceiveBufferSize(int size)` to small values - hoping that would fill up soon, but I can see that send operation completes without waiting for the client to consume enough data already written. ( which means that the small send and recv buffer size has no effect ) Another approach I took is to use Netty , and set `ServerBootstrap.setOption("child.sendBufferSize", 256);`, but even this is of not much use. Can anyone help me understand what I am doing wrong /

Original source