为什么更改SO_RCVBUF的值不起作用?

Flo*_*low 7 c sockets buffer setsockopt

我正在创建一个程序来创建一个RAW套接字,以便读取所有流量.在socket()和recvfrom()的调用之间(最后一个是循环以从缓冲区中取出所有数据包)我等待5s.

当我运行程序时,我用"快速模式"(快速填充缓冲区)中的hping3命令向我的程序发送大约200个数据包.一旦经过5秒,我的程序就会从缓冲区中提取大约150个数据包.

我尝试更改接收缓冲区的大小以获得更好的结果:

int a = 65535;
if ( (setsockopt(sockfd, 0, SO_RCVBUF, &a ,sizeof(int)) ) < 0 )
{
    fprintf(stderr, "Error setting sock opts..\n");
}
Run Code Online (Sandbox Code Playgroud)

但是,无论是"a",1还是10000000的值,它似乎都没有变化,我仍然可以从缓冲区获得~150个数据包.

有什么问题?

编辑:通过getsockopt呼叫验证«a»的值.

rut*_*ike 16

您可能也受操作系统的限制,如果它似乎仍然无法正常工作.检查以下值:

/proc/sys/net/core/rmem_default
/proc/sys/net/core/rmem_max
Run Code Online (Sandbox Code Playgroud)

如果你在示例中说的是TCP,而不是实际的原始套接字,你也可以检查以下值:

/proc/sys/net/ipv4/tcp_mem
Run Code Online (Sandbox Code Playgroud)

如果您在这些文件上运行cat,它们将显示当前设置.要永久更改它们,请使用sysctl.在开始更改之前写下这些设置是个好主意.这是一个关于进行这些更改的精彩教程:http://fasterdata.es.net/fasterdata/host-tuning/linux/.


Dan*_*ger 9

level论点setsockopt应该是SOL_SOCKET,而不是0:

int a = 65535;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int)) == -1) {
    fprintf(stderr, "Error setting socket opts: %s\n", strerror(errno));
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,缓冲区大小有一个由“/proc/sys/net/core/rmem_max”定义的上限。对于更大的缓冲区,您需要更改此全局限制,或者作为特权进程 (CAP_NET_ADMIN),您可以使用“SO_RCVBUFORCE”而不是“SO_RCVBUF”来忽略“rmem_max”限制。 (2认同)