【问题标题】:Is there a way to reduce the minimum lower limit of the socket send buffer size?有没有办法降低套接字发送缓冲区大小的最小下限?
【发布时间】:2015-06-04 02:00:00
【问题描述】:

我正在尝试将默认套接字发送缓冲区大小更改为较小的大小, 为了了解小型 UDP 数据报的 UDP 吞吐量如何受到影响。 为此,我使用 setsockopt 函数和选项 SO_SNDBUF 和 我正在尝试将缓冲区大小设置为 64 字节。我也用getsockoptsetsockopt 函数的结果。

这是我使用的代码:

int sock_fd;
struct sockaddr_in server_addr;
static int target_port = PORT;
int curr_snd_buff = 0;
int sk_snd_buff = 64;
socklen_t optlen;

if( (sock_fd=socket(AF_INET,SOCK_DGRAM,0)) == -1)
 fatal("in socket (client_udp)");

memset(&server_addr, 0, sizeof(struct sockaddr_in));

server_addr.sin_family = AF_INET;                                                                                          
server_addr.sin_addr.s_addr=inet_addr(args->a_ip);
server_addr.sin_port=htons(target_port); 

if ( sk_snd_buff > 0 )                                                                                                     >{                                                                                                     
  optlen = sizeof(sk_snd_buff);
  // get the default socketh send buffer size
 if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) {
    fatal("getting the socket send buffer");
  }
  printf("* default socket send buffer: %d\n", curr_snd_buff);
  printf("* attempting to change it to: %d\n", sk_snd_buff);
  if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sk_snd_buff, optlen) == -1) {
    fatal("changing the socket send buffer");
  }
  if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) {
    fatal("getting the socket send buffer");
  }
  printf("* new socket send buffer: %d\n", curr_snd_buff);
}

但是,我看到的是缓冲区大小的下限设置为 4608 每次我尝试设置一个小值时的字节数。这是上面代码的输出:

  • 默认套接字发送缓冲区:212992
  • 正在尝试将其更改为:2304
  • 新的套接字发送缓冲区:4608

通过尝试各种尺寸,我发现尺寸

  • 默认套接字发送缓冲区:212992
  • 正在尝试将其更改为:2305
  • 新的套接字发送缓冲区:4610

对于一些更大的尺寸,例如3000,是我的两倍 要求:

  • 默认套接字发送缓冲区:212992
  • 正在尝试将其更改为:3000
  • 新的套接字发送缓冲区:6000

通过网络搜索,我发现 Linux 将其中的值翻倍 设置时内核,并在查询时返回双倍值: Understanding set/getsockopt SO_SNDBUF

有没有办法降低套接字发送缓冲区大小的最小下限? 例如,将其设置为 64 字节?

【问题讨论】:

  • printf("* attempting to change it to: %d\n", sk_snd_buff);
  • 最小值固定为 2048(加倍)。最大值可以在/proc/sys/net/core/wmem_max 中设置。我想改变它的唯一方法是破解内核。
  • 补充@immibis 写的评论 valgrind 怎么说?
  • 我看不出减少套接字发送缓冲区大小将如何真正实现测试小数据报的 UDP 吞吐量的目标。只需发送小数据报。

标签: c sockets udp datagram setsockopt


【解决方案1】:

最小缓冲区大小是内核的一个函数。选项 SO_SNDBUF 的 Linux 文档有这样的说法:

设置或获取最大套接字发送缓冲区(以字节为单位)。当使用 setsockopt(2) 设置该值时,内核将该值加倍(以便为簿记开销留出空间),并且该加倍值由 getsockopt(2) 返回。默认值由 /proc/sys/net/core/wmem_default 文件设置,最大允许值由 /proc/sys/net/core/wmem_max 文件设置。此选项的最小(加倍)值为 2048。

(socket(7) 手册页)

不同系统的细节可能会有所不同,但是

  1. 这解释了您看到的加倍 - 缓冲区的传出字节容量是您设置的大小,但内核保留和报告的空间总共是两倍。
  2. 至少在 Linux 上,您无法将缓冲区设置为您希望的那样小。我猜想其他系统也会有相同数量级的限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2015-05-01
    相关资源
    最近更新 更多