Linux原始套接字缓冲区大小是否有256K的上限?

5

我在Centos中使用以下代码将原始套接字缓冲区大小更改为400 KB,但是我得到的结果与设置缓冲区大小为256 KB相同。有什么问题吗?或者这是套接字层的限制?内核版本为2.6.34。谢谢!

int       rawsock;
socklen_t socklen;
int       optval;
int       bufsize = 400 * 1024;

rawsock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (rawsock < 0) {
    my_log(LOG_ERR, "error creating raw socket");
    return rawsock;
}

optval = 0;
socklen = 4;
err = getsockopt(rawsock, SOL_SOCKET, SO_RCVBUF, &optval, &socklen);
bail_error(err);
my_log("socket RX original buffer size = %d", optval);

optval = 0;
socklen = 4;
err = getsockopt(rawsock, SOL_SOCKET, SO_SNDBUF, &optval, &socklen);
bail_error(err);
my_log("socket TX original buffer size = %d", optval);

err = setsockopt(rawsock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));
bail_error(err);

err = setsockopt(rawsock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
bail_error(err);

optval = 0;
socklen = 4;
err = getsockopt(rawsock, SOL_SOCKET, SO_RCVBUF, &optval, &socklen);
bail_error(err);
my_log("socket RX new buffer size = %d", optval);

optval = 0;
socklen = 4;
err = getsockopt(rawsock, SOL_SOCKET, SO_SNDBUF, &optval, &socklen);
bail_error(err);
my_log("socket TX new buffer size = %d", optval);

运行后的结果为:

socket RX original buffer size = 110592
socket TX original buffer size = 110592
socket RX new buffer size = 524288
socket TX new buffer size = 524288
3个回答

5

您的系统目前只能达到sysctl限制net.core.wmem_maxnet.core.rmem_max

如果该进程拥有超级用户权限,则可以使用SO_SNDBUFFORCESO_RCVBUFFORCE ioctls来覆盖这些限制。如果您的服务确实需要更大的缓冲区,除了开发或设计不良之外的任何其他原因,那么我建议您使用这种方法。通常情况下是没有这样的原因的,在这种情况下,我建议您改正应用程序/服务代码。

您可以在整个系统范围内修改这些限制,但它们将影响所有进程。通常默认设置很好,但在某些特殊情况下(例如具有非常宽但延迟较长的网络连接的嵌入式服务器?)可能希望对其进行修改。

要临时执行此操作(直到下一次启动),请以root身份运行sysctl -w net.core.wmem_max = bytessysctl -w net.core.rmem_max = bytes(其中bytes是以字节为单位的新限制的十进制数)。

要使更改永久生效,请添加

net.core.rmem_max=bytes
net.core.wmem_max=bytes

将以下内容翻译成中文:
将以下内容添加到您的/etc/sysctl.conf文件中,或者如果您的Linux发行版提供了一个新文件,则添加到/etc/sysctl.d/目录中。后者是更好的方法,因为它不会停止更新您的默认配置文件。
如果您想深入了解这些和其他套接字ioctl,可以查看内核net/core/sock.c文件和其中的sock_setsockopt()函数。

2
根据文档SO_RCVBUF :最大允许值由/proc/sys/net/core/rmem_max文件设置。 SO_SNDBUF :最大允许值由/proc/sys/net/core/wmem_max文件设置。
因此,限制可能取决于系统的配置方式。

0
有趣的副作用。我编写了一个AF_ALG程序,它接受一个输入文件(将随机选择),加密它,解密它,然后将解密后的明文与原始输入进行比较(使用cbc(aes))。"测试"程序似乎在212992字节处挂起。使用ctrl-z中断程序,并将其放入后台,他们报告读取了212992字节(我知道这对于测试数据来说是错误的,在这种情况下是/bin/zip,215792字节)。
检查了net.core.[rmem_max、wmem_max、rmem_default、wmem_default],它们都是212992。更新为2M后,之前失败的测试开始工作了。因此,这些限制似乎也会影响AF_ALG程序(我正在尝试公开一个加密加速器,并使用AF_ALG从用户空间对其进行一些压力测试)。

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