TCP三次握手与四次挥手详解

151 阅读4分钟

1、TCP三次握手、四次挥手

三次握手:

  1. 刚开始时,客户端close,服务端listen。
  2. 第1次握手:客户端发送SYN给服务端,指明客户端初始化序列号ISN(c),客户端处于SYN_Sent状态;(syn:同步序列编号)
  3. 第2次:服务端以自己的SYN应答,指定自己的初始化序列号ISN(s),ACK=ISN(客户端)+1,表示已收到客户端SYN;
  4. 第3次:客户端发送ACK(ACK=ISN(服务器)+1)报文表示收到服务端SYN

四次挥手:

  1. 刚开始双方都是established。
  2. 第1次挥手:客户端发送FIN报文,报文中指定一个序列号;
  3. 第2次:服务端发送ACK(ACK=客户端序列号+1)报文应答;
  4. 第3次:服务端发送FIN报文,报文中指定一个序列号;
  5. 第4次:客户端发送ACK(ACK=服务端序列号+1)报文应答;

2、为什么是三次握手,不是两次、四次?

TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。

不使用「两次握手」和「四次握手」的原因:

  • 「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
  • 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。

第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

3、第一/二/三次握手丢失了,会发生什么?

第一次握手丢失了,会发生什么?

当客户端想和服务端建立 TCP 连接的时候,首先第一个发的就是 SYN 报文,然后进入到 SYN_SENT 状态。

在这之后,如果客户端迟迟收不到服务端的 SYN-ACK 报文(第二次握手),就会触发「超时重传」机制,重传 SYN 报文,而且重传的 SYN 报文的序列号都是一样的

第二次握手丢失了,会发生什么?

客户端和服务端都会重传:

  • 客户端:客户端觉得可能自己的 SYN 报文(第一次握手)丢失了,于是客户端就会触发超时重传机制,重传 SYN 报文
  • 服务端:第二次握手丢失服务端就收不到第三次握手,于是服务端这边会触发超时重传机制,重传 SYN-ACK 报文,也就是第二次握手。

第三次握手丢失了,会发生什么?

因为第三次握手的 ACK 是对第二次握手的 SYN 的确认报文,所以当第三次握手丢失了,如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数。

注意:ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文。

4、为什么TIME_WAIT等待的时间是2MSL?

TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间

总之,2MSL时间是TCP连接关闭后需要等待的一段时间,以确保未被接收的分组从网络中彻底消失,从而避免出现“过早的连接终止”问题。