Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulate back pressure in TCP send

Tags:

java

netty

tcp-ip

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 /

like image 788
Bhaskar Avatar asked Apr 04 '12 16:04

Bhaskar


People also ask

What is TCP backpressure?

Backpressure refers to the buildup of data at an I/O switch when buffers are full and not able to receive additional data. No additional data packets are transferred until the bottleneck of data has been eliminated or the buffer has been emptied.

What is backpressure in stream processing?

What is backpressure. Streaming systems like Flink need to be able to gracefully deal with backpressure. Backpressure refers to the situation where a system is receiving data at a higher rate than it can process during a temporary load spike. Many everyday situations can cause backpressure.

What is back pressure concept?

Back pressure (or backpressure) is a resistance or force opposing the desired flow of fluid through pipes, leading to friction loss and pressure drop. The term back pressure is a misnomer, as pressure is a scalar quantity, so it has a magnitude but no direction.


2 Answers

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

like image 179
Peter Lawrey Avatar answered Oct 02 '22 17:10

Peter Lawrey


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

like image 28
secmask Avatar answered Oct 02 '22 17:10

secmask