c++ - getsockopt() 返回的值是之前由 setsockopt() 设置的值的两倍
问题描述
我正在尝试增加SO_RCVBUF
用于与 linux 设备驱动程序交互的原始套接字。默认值rmem_default/rmem_max
都太小了,163840。因此我使用以下堆栈溢出问题/答案来帮助我。一切正常,或者至少看起来是这样。但是,当我得到我为它设置的值时,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
解决方案
您给出的值setsockopt(SO_RCVBUF)
只是一个提示,而不是绝对值。如果需要,允许套接字提供程序使用不同的值。你得到的getsockopt(SO_RCVBUF)
是实际使用的价值。
您所看到的实际上是记录在案的行为:
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。
推荐阅读
- visual-studio-code - 如何以独立方式运行代码格式化程序(不执行 IDE)?
- html - Bootstrap 4.6 网格系统/Flexbox 不受父元素高度的限制?
- python - 如何在python tkinter中使用while循环实现多线程停止按钮
- angular - 从子组件在父组件中打开 Modal
- flutter - Flutter:[文件路径和名称].java 使用或覆盖了已弃用的 API
- python - 当父类定义了__call__时如何打印子类的签名
- database - post、img-thumbnail 和 file 的合适数据库模型是什么?
- python - python和EDSA secp256k1签名错误
- flutter - Flutter : PaginatedDataTable 现在可以获取页面了吗?
- r - 通过在 R 中对两列进行分组来求和行