我正在尝试增加用于与Linux设备驱动程序进行交互的原始套接字的SO_RCVBUF
。默认的rmem_default/rmem_max
都太小了163840。因此,我正在使用以下stack overflow question/answers来帮助我。一切正常,或者至少看起来像这样。但是,当我获得为SO_RCVBUF
设置的值时,它将返回我设置的值* 2?有人知道为什么吗?
int recv_val = SOCK_RCV_BUF_MAX; socklen_t size = sizeof(recv_val);
if(setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &recv_val, size) < 0)
{
fprintf(stderr, "Error setsockopt(SO_RCVBUF): %s\n", strerror(errno));
}
else
printf("Set the SO_RCVBUF to %d\n", recv_val);
recv_val = 0;
if (getsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &recv_val, &size) < 0)
{
fprintf(stderr, "Error getsockopt(SO_RCVBUF): %s\n", strerror(errno));
}
else if(recv_val == SOCK_RCV_BUF_MAX)
{
printf("Successfully set the buffer max to %d\n", SOCK_RCV_BUF_MAX);
}
else
printf("Failed to set the buffer to max (%d), val = %d\n", SOCK_RCV_BUF_MAX, recv_val);
输出
Set the SO_RCVBUF to 64000000
Failed to set the buffer to max (64000000), val = 128000000
更改为recv_val = SOCK_RCV_BUF_MAX/2
输出
Set the SO_RCVBUF to 32000000
Successfully set the buffer max to 64000000
如果我没有使用setsockopt()设置值,而是为套接字调用getsockopt(),则会得到正确的默认值
Failed to set the buffer to max (64000000), val = 163840
答案 0 :(得分:1)
您赋予setsockopt(SO_RCVBUF)
的值仅是提示,而不是绝对值。如果需要,套接字提供者可以使用其他值。从getsockopt(SO_RCVBUF)
得到的是所使用的 actual 值。
您所看到的实际上是已记录的行为:
http://man7.org/linux/man-pages/man7/socket.7.html
SO_RCVBUF
设置或获取最大套接字接收缓冲区(以字节为单位)。 使用setsockopt(2)
进行设置时,内核会将此值加倍(以留出簿记空间),并且getsockopt(2)
返回此加倍的值。默认值由/proc/sys/net/core/rmem_default
文件设置,最大允许值由/proc/sys/net/core/rmem_max
文件设置。此选项的最小值(两倍)为256。