一、TCP通信介绍

三次握手详细过程

  1. TCP A TCP B
  2. 1. CLOSED LISTEN
  3. 2. SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
  4. 3. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
  5. 4. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
  6. 5. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED
  7. Basic 3-Way Handshake for Connection Synchronization

在上图

  • 第二行中, A 发送了 SEQ 100,标志位是 SYN;
  • 第三行,B 发回了 ACK 101 与 SEQ 300,标志位是 SYN 与 ACK(两个过程合并了)。注意,ACK 是101意味着,B 希望接收到 101序列号开始的数据段。
  • 第四行,A 返回了空的数据,SEQ 101, ACK 301,标志位为 ACK。至此,双方的开始 SEQ (也就是 ISN)号100与300都被确认接收到了。
  • 第五行,开始正式发送数据包,注意的是 ACK 依旧是第四行的301,因为没有需要 ACK 的 SYN 了(第四行已经 ACK 完)。

以上,4 最后这个确认的过程,是可以带上数据的。

  1. The principle reason for the three-way handshake is to prevent old
  2. duplicate connection initiations from causing confusion. To deal with
  3. this, a special control message, reset, has been devised. If the
  4. receiving TCP is in a non-synchronized state (i.e., SYN-SENT,
  5. SYN-RECEIVED), it returns to LISTEN on receiving an acceptable reset.
  6. If the TCP is in one of the synchronized states (ESTABLISHED,
  7. FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), it
  8. aborts the connection and informs its user. We discuss this latter
  9. case under "half-open" connections below.

三次握手的原则设计是防止旧复用链接的初始化导致问题,为了解决此问题,我们设计了reset这个特别的控制信号来处理。
如果接收中的 TCP 在一个未同步状态如 SYN-SENT, SYN-RECEIVED,它会返回 reset 给对方。
如果 TCP 是同步状态中如(ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT),他会终止此连接并通知用户。

看起来有点绕,我们举个图例看看:

  1. TCP A TCP B
  2. 1. CLOSED LISTEN
  3. 2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
  4. 3. (duplicate) ... <SEQ=90><CTL=SYN> --> SYN-RECEIVED
  5. 4. SYN-SENT <-- <SEQ=300><ACK=91><CTL=SYN,ACK> <-- SYN-RECEIVED
  6. 5. SYN-SENT --> <SEQ=91><CTL=RST> --> LISTEN
  7. 6. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
  8. 7. SYN-SENT <-- <SEQ=400><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
  9. 8. ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK> --> ESTABLISHED
  10. Recovery from Old Duplicate SYN

这是 复用连接时,旧在途包发往新连接中的例子。

  • 3中,一个旧的重复的 SYN到达 B
  • 4中, B分别不出是否旧的,照样子正常回包。
  • 5中,A检测到 B 返回的ACK不正确,所以返回 RST(reset)
  • 6中,B接收到 RST(reset)信号,于是变成 LISTEN 状态。
  • 7中,新连接正常的 SYN终于到达了,三次握手正常进行。

这种是简化的情况,但是可以看出 TCP 是如何处理复用旧链接的包到达的。