Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effect of SO_SNDBUF

I am unable to make sense of how and why the following code segments work :

    /* Now lets try to set the send buffer size to 5000 bytes */
    size = 5000;
    err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,  &size, sizeof(int));
    if (err != 0) {
        printf("Unable to set send buffer size, continuing with default size\n");
    }

If we check the value of the send buffer, it is indeed correctly set to 5000*2 = 10000. However, if we try to send more than the send buffer size, it does send all of it. For example:

    n = send(sockfd, buf, 30000, 0);

    /* Lets check how much us actually sent */
    printf("No. of bytes sent is %d\n", n);

This prints out 30000.

How exactly did this work? Didn't the fact that the send buffer size was limited to 10000 have any effect? If it did, what exactly happened? Some kind of fragmentation?

UPDATE: What happens if the socket is in non-blocking mode? I tried the following:

  1. Changing buffer size to 10000 (5000*2) causes 16384 bytes to be sent
  2. Changing buffer size to 20000 (10000*2) causes 30000 bytes to be sent

Once again, why?

like image 595
Arun Avatar asked Nov 13 '11 19:11

Arun


2 Answers

The effect of setting SO_SNDBUF option is different for TCP and UDP.

  • For UDP this sets the limit on the size of the datagram, i.e. anything larger will be discarded.
  • For TCP this just sets the size of in-kernel buffer for given socket (with some rounding to page boundary and with an upper limit).

Since it looks like you are talking about TCP, the effect you are observing is explained by the socket being in blocking mode, so send(2) blocks until kernel can accept all of your data, and/or the network stack asynchronously de-queueing data and pushing it to the network card, thus freeing space in the buffer.

Also, TCP is a stream protocol, it does not preserve any "message" structure. One send(2) can correspond to multiple recv(2)s on the other side, and the other way around. Treat it as byte-stream.

like image 57
Nikolai Fetissov Avatar answered Nov 13 '22 13:11

Nikolai Fetissov


SO_SNDBUF configures the buffer that the socket implementation uses internally. If your socket is non-blocking you can only send up to the configured size, if your socket is blocking there is no limitation for your call.

like image 4
Werner Henze Avatar answered Nov 13 '22 12:11

Werner Henze