有没有办法减少套接字发送缓冲区大小的最小下限?

时间:2015-03-30 21:27:01

标签: c sockets udp datagram setsockopt

我正在尝试将默认套接字发送缓冲区大小更改为小尺寸, 为了了解UDP UDP数据报如何影响UDP吞吐量。 为此,我使用setsockopt函数和SO_SNDBUF选项 我试图将缓冲区大小设置为64字节。我还使用getsockopt来查看 setsockopt函数的结果。

以下是我使用的代码:

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

通过尝试各种尺寸,我发现尺寸< = 2304会发生这种情况 较大的尺寸,例如2305,我得到了更大的尺寸:

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

并且对于一些更大的尺寸,例如3000,我的尺寸加倍 请求:

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

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

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

1 个答案:

答案 0 :(得分:3)

最小缓冲区大小是内核的函数。选项SO_SNDBUF的Linux文档可以这样说:

  

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

(socket(7)manpage)

细节可能因系统而异,但

  1. 这解释了你看到的加倍 - 缓冲区输出字节的容量是你设置的大小,但是内核保留并报告两倍的空间。
  2. 至少在Linux上,你不可能像你想要的那样设置一个小的缓冲区。我猜其他系统会有相同数量级的约束。