套接字缓冲区大小未增加

5
int n = 0;
if ( 0 != getsockopt(iSockFd,SOL_SOCKET,SO_RCVBUF, &n, sizeof(n)))
{
    printf("Get socket option failed, errno: %d\n",errno);
}
else
{
    printf("Current socket buff len = %d\n", n);
}
n = 225280;
if(0 != setsockopt(iSockFd, SOL_SOCKET, SO_RCVBUF, (const void *)&n, sizeof(n)))
{
    printf("setsock err errno %d\n", errno);
}
else
{
    printf("setsock opt success\n");
}
n = 0;
if ( 0 != getsockopt(iSockFd,SOL_SOCKET,SO_RCVBUF, &n, sizeof(n)))
{
    printf("Get socket option failed, errno: %d\n",errno);
}
else
{
    printf("After setting socket buff len = %d\n", n);
}

输出结果为 -

当前套接字缓冲区长度 = 41600

设置套接字选项成功

设置套接字缓冲区后长度为 41600。

看起来接收缓冲区大小没有增加,有任何想法是为什么会这样吗?

提前感谢!


该平台可以自由调整实际值的上下限。一个这么大的套接字缓冲区并没有太多意义。 - user207421
@Coder:你能分享一下Linux内核的版本以及以下文件中的配置,以便更好地了解情况吗? /proc/sys/net/ipv4/tcp_moderate_rcvbuf /proc/sys/net/ipv4/tcp_rmem /proc/sys/net/core/rmem_default /proc/sys/net/core/rmem_max /proc/sys/net/ipv4/tcp_rmem - Karthik Balaguru
2个回答

4
如果内核版本更新(2.6.17或更高),请检查文件/proc/sys/net/ipv4/tcp_moderate_rcvbuf以验证是否启用自动调整。如果tcp_moderate_rcvbuf的值为1,则已启用自动调整。在这种情况下,接收缓冲区将由内核动态更新,并绑定到/proc/sys/net/ipv4/tcp_rmem中的值。检查是否达到了此限制。
如果内核版本较旧,请检查SO_RCVBUF是否受/proc/sys/net/core/rmem_default和/proc/sys/net/core/rmem_max中的值限制。在TCP的情况下,还要检查/proc/sys/net/ipv4/tcp_rmem的值。
还要注意,“使用setsockopt()手动调整套接字缓冲区大小会禁用自动调整”。这是关于Linux调优的好链接http://www.psc.edu/index.php/networking/641-tcp-tune

你自相矛盾。你的第一段建议检查自动调谐,但是你的最后一段解释说设置缓冲区大小会禁用自动调谐。那么如果问题中的代码会禁用它,自动调谐怎么能阻止在这里设置套接字缓冲区呢?自动调谐与问题完全无关。 - Mecki

0

要始终查看 man 页面所说的内容:

SO_RCVBUF
设置或获取以字节为单位的最大套接字接收缓冲区大小。 当使用 setsockopt(2) 设置此值时,内核会将该值加倍(以便为簿记开销留出空间),并且 getsockopt(2) 会返回这个加倍后的值。默认值由 /proc/sys/net/core/rmem_default 文件设置,最大允许值由 /proc/sys/net/core/rmem_max 文件设置。此选项的最小(加倍)值为256。

http://man7.org/linux/man-pages/man7/socket.7.html

因此,存在一个上限,任何尝试设置更大值的操作都会悄悄失败,这意味着不会出现错误,只是大小没有增加。几乎所有现有系统都存在这样的限制,而不仅仅是Linux。还要注意,即使您的setsockopt()成功,getsockopt()也会返回一个更大的值,因为该值在内部被加倍(这是Linux独有的,其他系统不会这样做)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接