c - SO_SNDBUF 的作用

标签 c linux sockets setsockopt

我无法理解以下代码段的工作方式和原因:

    /* 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 个字节

再一次,为什么?

最佳答案

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

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

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

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

关于c - SO_SNDBUF 的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8114280/

相关文章:

c - 加载从数组矩阵到数组的数组矩阵问题

c++ - 有没有办法将 cin.fail 和 cin.clear 翻译成 C 编程语言?

linux - 我在哪里添加系统调用到 linux 内核源代码

sockets - 是否可以在一个程序上打开多个端口?

Java Socket 非阻塞读

c - linux线程和内存/变量

c - 结构末尾的填充物用于 future 增长

java - 如何在我的服务器上安装和配置 OpenTripPlanner?

javascript - HTML img标签自动刷新浏览器导致图片撕裂

java - 在将 Sockets 与 NIO 结合使用时防止内存使用率过高