Linux套接字缓冲区溢出是如何发生的?

15

我有一个Java阅读器应用程序,它在Linux 64位平台(2.6.18)上从多播套接字中读取数据。此套接字大小已设置为2 MB。当阅读器无法快速读取数据时,套接字会"溢出",即缓冲区中的数据包会被丢弃。

我想知道的是Linux内核如何将数据包从套接字缓冲区中丢弃。我认为套接字缓冲区本身就是一个FIFO缓冲区。但是,如果它已满,会发生什么情况?下一个数据包会被丢弃吗(并且缓冲区内容不会改变)?还是新数据包会替换缓冲区中的旧数据包?如果是后者,哪个数据包会被替换(最老的?最年轻的?随机选择的?)?

感谢任何见解。

2个回答

10

当缓冲区已满时,传入的数据包将被丢弃。已经存在于缓冲区内的数据包不会被修改或替换。


1
谢谢。您有支持这个说法的链接/来源吗? - AtomicJake
@AtomicJake:这是网络设计的标准实践。或者说:操作系统还能做什么?如果套接字缓冲区已满,TCP堆栈会将窗口大小设置为0。状态中的所有传入数据包都将被视为无效(不适合窗口),因此被丢弃。请阅读RFC793,查找“接收窗口”。 - Dummy00001
你对于TCP的理解是正确的,但我特别询问的是多播UDP读取套接字。据我所知,网络中每个传入的数据包都会被复制到一个独立的套接字缓冲区中(每个读取者一个缓冲区)。因此,每个读取者以不同的速度清空套接字。在Linux上,当缓冲区已满时,新的数据包会被简单地丢弃吗?还是(像环形缓冲区一样)覆盖最旧的条目?我认为这两种实现都是合法的。 - AtomicJake

2

对JS Bangs的回答进行补充。

网络堆栈中不仅有这个位置可以丢弃数据包。套接字接收缓冲区在层次结构中较高,且特定于用户套接字。在接近硬件的另一个位置(至少在Linux中),是设备驱动程序和NET_RX softirq之间的队列(请参见netif_rx())。这些丢失将导致netstat -i输出中的RX-DRP列增加。


谢谢。我已经通过“sar”确认,确实在应用程序读取的套接字缓冲区中丢失了数据包。当应用程序读取速度太慢而导致数据包丢失时,我可以看到计数器。 - AtomicJake

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