Linux 中的 TCP 接受队列是什么类型的队列——先进先出/后进先出/其他?

Linux 中的 TCP 接受队列是什么类型的队列——先进先出/后进先出/其他?

我想知道Linux中的TCP接受队列是先进先出还是后进先出,还是任何其他类型的队列?

从另一个角度问同样的问题:accept()产生连接的顺序是否与到达主机的顺序相同?

答案1

引用man 2 accept

它提取待处理连接队列中的第一个连接请求

所以,先进先出原则。“队列”实际上是这么说的;这个词总是指 FIFO 数据结构(就像邮局里的队列一样,你需要第一个到那里才能得到服务)。

连接的顺序与到达主机的顺序相同吗?

连接未“到达”!这就是这个表述中的问题所在,也是歧义的根源。

我们来看看一个简化的TCP状态机视图

简化的 TCP 状态机
作者:技能100,来源, CC-BY-SA 3.0

现在,直观上并不清楚谁应该是队列中的“第一个”:第一个收到 SYN 的人? SYN-ACK 可以发送到的第一个目标?或者第一个收到确认的人?

但仔细想想,内核知道套接字已准备好accept返回某些内容的时刻是当它收到ACK.这就是将事物插入接受队列的顺序。

但是,请注意,这是高度随机的:它取决于两端对 SYN、SYN-ACK 数据包的反应速度以及传输这些数据包所需的时间。

您通常不能假设接受队列中的第一个条目是第一个启动连接的客户端。这在过去困扰了许多网络协议设计者,在您需要多方连接以中继消息的情况下(您实际上无法知道是否需要为以后连接的节点存储消息;您必须有逻辑)最重要的是避免迟到的加入者问题)。


这个答案是一个历史悠久的经典,并且可能有比你想知道的更多的内部结构。

相关内容