Linux 本地丢弃 UDP 数据包(接收缓冲区溢出)



我构建了一个简单的测试程序,每 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(由于数据包标头,比您发送的数据包批次少一点(会导致数据包被丢弃。即使getsockopt的结果分别是250,000和200,000。

最新更新