Linux UDP 接收缓冲区的最大大小

Posted

技术标签:

【中文标题】Linux UDP 接收缓冲区的最大大小【英文标题】:Linux UDP max size of receive buffer 【发布时间】:2013-05-09 11:04:13 【问题描述】:

是多少?我认为它仅受可用 RAM 的限制,但是当我设置时

rmem_max 为 5GB:

echo 5000000000 > /proc/sys/net/core/rmem_max

以及 4GB 的实际套接字缓冲区(在 Erlang 中):

gen_udp:listen(Port, [recbuf, 4000000000])

当我测量缓冲区利用率时,它显示:

# netstat -u6anp | grep 5050
udp6  1409995136      0 :::5050  :::*       13483/beam.smp

我不能超过这个 1.4GB。对于较小的缓冲区大小,例如500MB,实际缓冲区大小与配置值匹配。我的系统是 Debian 6.0,机器有 50GB RAM 可用。

【问题讨论】:

它在哪里说它仅受可用 RAM 限制?为什么你认为你需要一个 4GB 的缓冲区? 它没有。它也没有说它以任何其他方式受到限制。我需要这样一个缓冲区来避免在较长的网络流量窥视期间丢失数据。 相反。它说内核可能会向上或向下调整您提供的值,并建议您致电getsockopt() 以查看实际分配的值。我很难相信你需要 4GB 来处理流量高峰。也许你应该读得更快。 “它说内核可能会向上或向下调整你提供的值”你在哪里找到这个信息?如何在一个线程中比“while(true)recv(Socket)”更快地阅读?为了测试,我在收到数据包后丢弃它们。我每秒可以读取 60000 个 600B 大小的数据包,而生成 200000/s 的流量不是问题。在这些条件下,缓冲区会在 16 秒后填满。你不能客观地说 10s 是一瞥,但 20s 不是。我宁愿期待,有了更好的机器,我能够在偷看更长的时间内存活下来。 20 多年来,我一直在 man 页面中阅读该声明。这不是新闻。你怎么知道你在接收端丢包? 【参考方案1】:

linux 好像有限制。 我尝试将 rmem_max 设置为 2^32-1 并成功。

   root@xxx:/proc/sys/net/core# echo 2147483647 > rmem_max
   root@xxx:/proc/sys/net/core# cat rmem_max
   2147483647

2^32 太多了:

   root@xxx:/proc/sys/net/core# echo 2147483648 > rmem_max
   root@xxx:/proc/sys/net/core# cat rmem_max
   -18446744071562067968

设置为 5000000000 产量:

   root@xxx:/proc/sys/net/core# echo 5000000000 > rmem_max
   root@xxx:/proc/sys/net/core# cat rmem_max
   705032704

我已经在 python 中测试了设置和获取套接字接收缓冲区

   ss.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, bufferSize)
   print ss.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)

如果 'bufferSize' 小于 1024^3 程序打印两倍的 'bufferSize',否则它会回落到 256。

705032704*2 = 141006540​​8的值接近netstat得到的1409995136。

【讨论】:

确实,我还没有验证放入 rmem_max 的实际值。谢谢。看起来缓冲区大小被限制为signed int,没有明确的原因。 哪个内核版本? 32 位还是 64 位? @Massimo 这个家伙有 50 GB 的 RAM,我认为假设 64 位是可以的 @lennyy 使用 CPU 的 Physical Address Extension 功能,32 位操作系统可以使用 address up to 64GB of RAM。只是单个 32 位进程不能处理超过 2-4GB 的最大值。但是操作系统本身可以,并且它可以通过为每个进程的地址空间使用虚拟内存来在多个进程之间分割 RAM。 @RemyLebeau 哦,有趣,我不知道。不过有道理。感谢分享【参考方案2】:

2^32-1(2147483647,最大32位有符号整数)

root@root@localhost:~# sysctl -w net.core.rmem_max=2147483647
net.core.rmem_max = 2147483647

root@localhost:~# sysctl -w net.core.rmem_max=2147483648
sysctl: setting key "net.core.rmem_max": Invalid argument
net.core.rmem_max = 2147483648

在尝试设置更大的值时,回显到 /proc 文件系统似乎会溢出。

【讨论】:

哪个内核版本? 32 位还是 64 位?

以上是关于Linux UDP 接收缓冲区的最大大小的主要内容,如果未能解决你的问题,请参考以下文章

请教Linux关于UDP最大缓冲区设置

winsocket udp和tcp编程,缓冲区应该设置多大?

linux udp setsockopt函数啥进修

如何在 Winsock 中查找当前使用的 UDP 接收缓冲区大小

修改linux系统socket缓冲区大小

Linux内核调优部分参数说明