假设两台主机 A 和 B 都尝试彼此建立连接,但是 A 的 SYN 在 B 的 SYN 到达 A 之前就到达了 B。
我的答案是 A 将发送 SYN ACK 并忽略来自 B 的 SYN。我对吗?
答案1
将会建立两个连接。TCP 无法感知状态 - 两个连接都没有对方连接的概念。
例如:
Connection 1:
192.168.1.5 sends SYN to 192.168.1.6 on port 80.
Connection 2:
192.168.1.6 sends SYN to 192.168.1.5 on port 80.
为了继续进行此操作,两者都需要在端口 80 上有一个监听服务,因此每个服务都需要在 TCP 端口 80 上监听某个服务,并且该服务将接收 SYN 并使用 SYN-ACK 进行响应:
Connection 1:
192.167.1.6 responds with SYN-ACK to 192.168.1.5 on port 80
Connection 2:
192.167.1.5 responds with SYN-ACK to 192.168.1.6 on port 80
请记住,这些监听服务位于相反的机器上 - 无法知道对方是否也收到了 SYN,因此没有理由它们不应该发送 SYN-ACK。
根据 TCP 协议规定,一旦发起方收到 SYN-ACK,它将响应:
Connection 1:
192.168.1.5 sends ACK to 192.168.1.6 on port 80.
Connection 2:
192.168.1.6 sends ACK to 192.168.1.5 on port 80.
现在您有两个独立的连接,并且 TCP 握手已完成。正如 SvW 在评论中提到的那样:如果这是件坏事,则由发起连接的任何应用程序来确定此状态是否存在并确定要断开哪个连接 - 这部分不是 TCP 的工作。
答案2
请记住,TCP 套接字是四元组 srcHost:srcPort:dstHost:dstPort,并且要建立连接,一个主机必须监听特定的端口。
因此对于第一个连接,A:portA:B:portB 套接字将是(B 在 portB 上监听):
- 在 A 上处于 SYN_SENT 状态
- B 上处于 SYN_RECEIVED 状态
对于第二个连接,A:portA':B:portB'(A 监听 portA')
- 在 B 上的 SYN_SENT
- 在 A 上处于 LESTEN 状态
答案3
假设两台主机使用同一对端口,那么将建立连接。实际上,这种情况不会发生,因为当主机建立连接时,它们使用随机本地端口和众所周知的远程端口,因此两台主机不会使用相同的端口对。即使它们确实使用相同的端口对,时间也必须恰到好处,以便 SYN 在飞行过程中相互传递。如果一台主机在发送自己的 SYN 之前收到 SYN,那么它将以 RST 进行响应。