Linux 本地丢弃 UDP 数据包(接收缓冲区溢出)
Linux locally dropping UDP packets (Receive buffer overflow)
我构建了一个简单的测试程序,每 250 毫秒发送 100 个 UDP 数据包,每个大小为 1000 字节。我发现两个单独的 linux 盒子正在丢弃其中一些数据包。
我的期望是,当我写入 100 个 UDP 数据包时,内核缓冲区能够保留所有这些数据包。 netstat -us
表示每个被丢弃的数据包都有 RcvbufErrors
。所以看起来内核接收缓冲区溢出了。但是我不明白为什么。
/proc/sys/net/core/rmem_default
显示值为 212992,因此我认为增加该值不会有帮助,因为它已经大于该测试发送的 100kB 批次。
我 运行 第二个测试,我每 10 毫秒发送 50 个 UDP 数据包,每个大小为 1000 字节。我发现 没有数据包 在这个测试中被丢弃。这向我表明 100kB 会溢出缓冲区,而 50kB 不会。它还进一步表明我不受 CPU 限制或数据包限制——此测试发送数据包的速度比第一个快很多倍。
我使用的两台 linux 机器:macbook 上的 virtualbox 和 AWS m5a.xlarge
.
我的测试程序:https://github.com/theicfire/rando/tree/master/udp-fail-batch-stack-overflow
您正处于缓冲区大小的边缘,尽管看起来并非如此。
rmem_default
的值并不意味着正好有那么多字节可供使用。我在阅读设置 SO_RECVBUF
:
的 man page 时得到了提示
The kernel doubles this value (to allow space for bookkeeping
overhead) when it is set using setsockopt(2), and this doubled
value is returned by getsockopt(2).
这意味着内核正在占用该缓冲区的一部分。可能是一个很大的数量(即它可能用掉了 rmem_default
设置的一半。
将 SO_RCVBUF
选项设置为 125,000 可阻止丢包。将其设置为 100,000(由于数据包 headers,比您发送的数据包批次少一点)会导致数据包被丢弃。尽管getsockopt的结果分别是25万和20万
我构建了一个简单的测试程序,每 250 毫秒发送 100 个 UDP 数据包,每个大小为 1000 字节。我发现两个单独的 linux 盒子正在丢弃其中一些数据包。
我的期望是,当我写入 100 个 UDP 数据包时,内核缓冲区能够保留所有这些数据包。 netstat -us
表示每个被丢弃的数据包都有 RcvbufErrors
。所以看起来内核接收缓冲区溢出了。但是我不明白为什么。
/proc/sys/net/core/rmem_default
显示值为 212992,因此我认为增加该值不会有帮助,因为它已经大于该测试发送的 100kB 批次。
我 运行 第二个测试,我每 10 毫秒发送 50 个 UDP 数据包,每个大小为 1000 字节。我发现 没有数据包 在这个测试中被丢弃。这向我表明 100kB 会溢出缓冲区,而 50kB 不会。它还进一步表明我不受 CPU 限制或数据包限制——此测试发送数据包的速度比第一个快很多倍。
我使用的两台 linux 机器:macbook 上的 virtualbox 和 AWS m5a.xlarge
.
我的测试程序:https://github.com/theicfire/rando/tree/master/udp-fail-batch-stack-overflow
您正处于缓冲区大小的边缘,尽管看起来并非如此。
rmem_default
的值并不意味着正好有那么多字节可供使用。我在阅读设置 SO_RECVBUF
:
The kernel doubles this value (to allow space for bookkeeping
overhead) when it is set using setsockopt(2), and this doubled
value is returned by getsockopt(2).
这意味着内核正在占用该缓冲区的一部分。可能是一个很大的数量(即它可能用掉了 rmem_default
设置的一半。
将 SO_RCVBUF
选项设置为 125,000 可阻止丢包。将其设置为 100,000(由于数据包 headers,比您发送的数据包批次少一点)会导致数据包被丢弃。尽管getsockopt的结果分别是25万和20万