理解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假定发送/接收缓冲区的一半用于内部 内核结构; 因此系统是可观察到的两倍 电线。 [...]