Skip to content

TCP的三次握手与四次挥手

作者:guo-zi-xin
更新于:1 年前
字数统计:1.3k 字
阅读时长:4 分钟

TCP三次握手

这里我们将发出方成为客户端, 接收方成为服务端。 TCP建立连接主要分为三部分, 可简单描述为

  • 客户端向服务端发起TCP请求
  • 服务端响应客户端, 同意建立TCP连接
  • 客户端向服务端最后确认TCP连接建立
TCP三次握手
术语含义
SYN同步序列编号(Synchronize Sequence Numbers),表示向接收方建立TCP连接的请求,仅在三次握手期间有效
SEQ/seqTCP数据包序列号(Sequence Number),在TCP发送的每个数据包都会随机生成一个序列号,该序列号用于接受放对数据包的接收确认,防止丢失以及数据接收完毕后按序列号顺序组装
ACK确认编号(Acknowledgement Number),数据包的确认标志,标识对发出方发出数据包的接收确认
SYN_SENT客户端发送同步标志SYN后,进入SYN_SENT状态
SYN_RECV服务端确认客户端的SYN包并发送SYN包后,进入SYN_RECV状态
ESTABLISHED客户端与服务端发送同步标识SYN后,对方确认后进入TCP建立状态

三次握手详细过程

  1. 建立连接时,客户端向服务端发SYN包(该数据包假设SYN为j,随机产生一个值seq=x),并将该数据包发送给服务端,客户端进入SYN_SENT状态,等待Server确认
  2. 服务端收到SYN包,必须先确认客户的SYN,发送一个ACK值为j+1的确认数据包,同时也向客户端发送一个SYN包(假设SYN=k,随机产生一个值seq=y),即发送SYN+ACK包,然后服务端进入SYN_RECV状态
  3. 客户端接收到服务端的SYN+ACK包之后,客户端进入ESTABLISHED状态,并对服务端发送的SYN包进行确认,发送确认包ACK(ack=y+1),服务端接收到客户端的ACK包之后,也进入ESTABLISHED状态,至此TCP连接成功

TCP四次挥手

在数据传输完毕之后会进行TCP四次握手即是TCP连接关闭,TCP需要进行四次挥手的原因在于TCP连接是双全工,即双方通信,每个方向都需要进行单独关闭

TCP四次挥手

四次挥手详细过程

  1. 最开始的一次挥手,客户端发起 FIN 包,客户端进入 FIN_WAIT_1 状态,TCP规定,即使 FIN 包不携带数据,也要消耗一个序列号
  2. 第二次挥手,服务端接收到了 FIN 包,发出确认包 ACK 并带上自己的序列号,服务端进入 CLOSE_WAIT 状态,这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话, 客户端依然需要接收,客户端接收到服务端发送的 ACK 后,进入到 FIN_WATI_2 状态。
  3. 第三次挥手, 服务端数据发送完毕之后,向客户端发送 FIN 包,半连接状态下服务器可能又发送了一些数据,服务器此时进入了 LAST_ACK状态
  4. 第四次挥手,客户端收到服务器的 FIN 包之后, 发送确认包 ACK 此时客户端进入 TIME_WAIT 状态,此时TCP连接还没有释放,必须经过两个 MSL 后,才会进入 CLOSED状态, 可以看出服务端结束TCP连接的时间要比客户端早一些

为什么建立连接时需要握手三次,关闭连接时需要四次呢?

  • 在TCP握手的时候,接收端发送 SYN+ACK 的包是将一个 ACK 和一个 SYN 合并到一个包中, 所以减少了一次包的发送,完成三次握手
  • 对于四次挥手,TCP是全新工程通信,在主动关闭放发送 FIN 包之后,接收端可能还要发送数据,不能立即关闭服务器端到客户端的数据通道,所以并不能将服务器端的 FIN 包盒对客户端的 ACK 包合并发送, 只能先确定 ACK ,然后服务器等到无需发送数据时候在发送 FIN 包,所以四次挥手时候必须是四次数据包的交互。

四次挥手结束后,为什么客户端没有立刻关闭呢

  • 为了确保第四次挥手的确认消息到达服务端
  • 如果服务端在规定时间内未收到最后的确认消息,会冲洗内进行第三次挥手请求断开连接,客户端重新发送确认消息
  • MSL 是报文的最长生存时间,两个 MSL 是在网络中来回两个报文所需要的最长时间,如果超过了这个时间,客户端没有重新收到断开连接的请求,说明四次挥手顺利完成,可以断开连接了。

引用

Internet通信
https://heyingye.github.io/2018/03/02/Internet%E9%80%9A%E4%BF%A1%EF%BC%88%E4%BA%8C%EF%BC%89/

人生没有捷径,就像到二仙桥必须要走成华大道。