一旦服务器从客户端应用程序获得 SYN 数据包,它就会进入 SYN_RECV 状态。
如果从同一个客户端应用程序收到 2 个 SYN 数据包,服务器端会发生什么?
一旦服务器从客户端应用程序获得 SYN 数据包,它就会进入 SYN_RECV 状态。
如果从同一个客户端应用程序收到 2 个 SYN 数据包,服务器端会发生什么?
基本上,接收重复 SYN 的 TCP 将 SYN,ACK 它们,但它会收到重复的 RST。
RFC 793,传输控制协议,第 3.4 节。建立连接正好解释了这种情况:
3.4. 建立连接
“三次握手”是用于建立连接的过程。这个过程通常由一个 TCP 发起并由另一个 TCP 响应。如果两个 TCP 同时启动该过程,该过程也可以工作。当同时尝试发生时,每个 TCP 都会收到一个“SYN”段,该段在发送“SYN”后不携带确认。当然,旧的重复“SYN”段的到来可能会使接收者觉得同时启动连接正在进行中。正确使用“重置”段可以消除这些情况的歧义。
在本节的后面,它会更详细地介绍:
三次握手的主要原因是为了防止旧的重复连接启动造成混乱。为了解决这个问题,已经设计了一个特殊的控制消息,reset。如果接收 TCP 处于非同步状态(即 SYN-SENT、SYN-RECEIVED),它会在接收到可接受的复位后返回 LISTEN。如果 TCP 处于同步状态之一(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT),它会中止连接并通知其用户。我们在下面的“半开”连接下讨论后一种情况。
TCP A TCP B 1. CLOSED LISTEN 2. SYN-SENT --> <SEQ=100><CTL=SYN> ... 3. (duplicate) ... <SEQ=90><CTL=SYN> --> SYN-RECEIVED 4. SYN-SENT <-- <SEQ=300><ACK=91><CTL=SYN,ACK> <-- SYN-RECEIVED 5. SYN-SENT --> <SEQ=91><CTL=RST> --> LISTEN 6. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED 7. SYN-SENT <-- <SEQ=400><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED 8. ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK> --> ESTABLISHED Recovery from Old Duplicate SYN Figure 9.
作为从旧副本恢复的简单示例,请考虑图 9。在第 3 行,旧副本 SYN 到达 TCP B。TCP B 无法判断这是旧副本,因此它正常响应(第 4 行)。TCP A 检测到 ACK 字段不正确,并返回一个 RST(重置),并选择其 SEQ 字段以使该段可信。TCP B 在收到 RST 后,返回 LISTEN 状态。当原始的 SYN(双关语)最终到达第 6 行时,同步正常进行。如果第 6 行的 SYN 在 RST 之前到达,则在双向发送 RST 时可能会发生更复杂的交换。
RFC 是 TCP 的定义,你应该参考它。还有后来的 RFC 对其进行了更新(RFC 1122、3168、6093、6528)。
服务器将简单地重置客户端重新发送的同步数据包,并将其视为重复数据包。
基本上,由于 TCP 是可靠的协议,因此 TCP 握手成功后只有实际应用程序数据被传输。
Client --------------- Server
在此期间,任何数据包被丢弃的主机都会重新传输数据包。但如果它被认为是重复数据包,请重置连接。