理解set / getsockopt SO_SNDBUF

您好我有以下程序来检查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

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

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

 [...]

     SO_SNDBUF
              设置或获取最大套接字发送缓冲区的字节数。 该ker-
               nel翻倍这个价值(为记账开销留出空间)
              当它使用setsockopt()设置时,这个加倍的值是
              由getsockopt()返回。 默认值是由
               wmem_default sysctl和允许的最大值是由
               wmem_max sysctl。 这个选项的最小值(加倍)是
               2048。
 [...]

笔记
        Linux假定发送/接收缓冲区的一半用于内部
       内核结构; 因此系统是可观察到的两倍
       电线。
 [...]