如果我们在套接字上设置了
SO_REUSEPORT
,那么我们可以让多个套接字同时监听相同的IP:Port
条件。我阅读了多篇关于以下疑问的博客文章,但我仍然不清楚如何考虑所有动态。
假设有两个不同的进程 A 和 B,假设它们正在“监听”同一个
IP:Port
。现在,如果一个新请求进入一个端点,该端点将由进程 B 而不是 A 提供服务,操作系统如何知道要传输该请求的进程?
简单的答案。 它没有。
让我们看看当进程打开套接字时会发生什么。
listen()
系统调用告诉 linux 内核 “嘿,请为一些针对我的请求做好准备”
此时分配了这个socket对应的两个队列,分别是SYN和Accept Queues。
SYN 队列: 当一个
SYN
数据包到这个IP:Port
到达时,内核将其放入此队列并发回SYN-ACK
。此时连接状态为SYN-Received
.
请注意,如果两个不同的套接字有两个 SYN 队列监听相同的
IP:Port
组合,内核 randomly
将该数据包分配给其中一个,即使该数据包正在为实际请求设置基础另一个套接字/进程。
Accept Queue:当
ACK
从客户端到达时,连接状态变为ESTABLISHED
,实际连接对象转移到socket的Accept Queue。这里执行了更多验证,但与问题无关。
生成套接字的进程不断调用
accept()
系统调用,它基本上从自己的接受队列中弹出请求并处理它。
因此我们可以从上面推断出,内核只是简单地将传入请求随机放入其中一个监听套接字,并且所选择的套接字可能不是应该处理请求的套接字,在这种情况下,客户端请求最终会超时.