一尘不染

了解set / getsockopt SO_SNDBUF大小加倍

linux

嗨,我有以下程序来检查UDP套接字的发送缓冲区大小。但是,我的返回值让我有些困惑。我使用以下简单的应用程序:

#include <sys/socket.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 int sockfd, sendbuff;
 socklen_t optlen;

 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if(sockfd == -1)
     printf("Error");

 int res = 0;

 // Get buffer size
 optlen = sizeof(sendbuff);
 res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

 if(res == -1)
     printf("Error getsockopt one");
 else
     printf("send buffer size = %d\n", sendbuff);

 // Set buffer size
 sendbuff = 98304;

 printf("sets the send buffer to %d\n", sendbuff);
 res = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));

 if(res == -1)
     printf("Error setsockopt");


 // Get buffer size
 optlen = sizeof(sendbuff);
 res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

 if(res == -1)
     printf("Error getsockopt two");
 else
     printf("send buffer size = %d\n", sendbuff);

 return 0;
}

我的机器上的输出是:

发送缓冲区大小= 129024

将发送缓冲区设置为98304

新的发送缓冲区大小= 196608

任何人都可以在这里弄清楚我在做什么错或如何解释输出吗?


阅读 691

收藏
2020-06-03

共1个答案

一尘不染

你没做错什么 在设置时,Linux将值加倍(在内核内),并在查询时返回加倍的值。 man 7 socket说:

[...]

    SO_SNDBUF
              Sets or gets the maximum socket send buffer in bytes.  The  ker-
              nel doubles this value (to allow space for bookkeeping overhead)
              when it is set using setsockopt(), and  this  doubled  value  is
              returned  by  getsockopt().   The  default  value  is set by the
              wmem_default sysctl and the maximum allowed value is set by  the
              wmem_max sysctl.  The minimum (doubled) value for this option is
              2048.
[...]

NOTES
       Linux assumes that half of the send/receive buffer is used for internal
       kernel structures; thus the sysctls are twice what can be  observed  on
       the wire.
[...]
2020-06-03