SO_SNDBUF 的影响

发布于 2024-12-15 13:28:50 字数 828 浏览 5 评论 0原文

我无法理解以下代码段如何以及为何工作:

    /* 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");
    }

如果我们检查发送缓冲区的值,它确实被正确设置为 5000*2 = 10000。 但是,如果我们尝试发送超过发送缓冲区大小的内容,它会发送全部内容。例如:

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

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

打印出 30000。

这到底是如何工作的?发送缓冲区大小限制为 10000 没有任何影响吗?如果确实如此,到底发生了什么?某种碎片化?

更新:如果套接字处于非阻塞模式会发生什么?我尝试了以下操作:

  1. 将缓冲区大小更改为 10000 (5000*2) 会导致发送 16384 字节
  2. 将缓冲区大小更改为 20000 (10000*2) 会导致发送 30000 字节

再次,为什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哑剧 2024-12-22 13:28:50

设置SO_SNDBUF选项的效果对于TCP和UDP是不同的。

  • 对于 UDP,这设置了数据报大小的限制,即任何较大的数据都将被丢弃。
  • 对于 TCP,这只是设置给定套接字的内核缓冲区的大小(对页面边界进行一些舍入并设置上限)。

由于看起来您正在谈论 TCP,因此您观察到的效果是通过套接字处于阻塞模式来解释的,因此 send(2) 会阻塞,直到内核可以接受所有数据和/或网络堆栈异步地将数据出队并将其推送到网卡,从而释放缓冲区中的空间。

另外,TCP 是一种流协议,它不保留任何“消息”结构。一个 send(2) 可以对应另一侧的多个 recv(2),反之亦然。将其视为字节流。

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.

傲影 2024-12-22 13:28:50

SO_SNDBUF 配置套接字实现内部使用的缓冲区。如果您的套接字是非阻塞的,您只能发送配置的大小,如果您的套接字是阻塞的,则您的调用没有限制。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文