TCP协议建立连接的过程-三次握手

计算机网络基础知识
2021-05-17 14:29 · 阅读时长3分钟
小课

所谓三次握手指的是在TCP连接建立时,建立连接的两台主机之间会发送三个数据包,用来建立有效的连接。

TCP协议建立连接的过程-三次握手

第一次握手:主机A请求连接,向主机B发送数据包,主机A状态从CLOSED转为SYN-SENT,本次发送数据包头部有以下特点:

  • SYN标志为1,表示请求建立连接。
  • ACK标志为0,表示该数据包不是回应数据包。
  • 序列号码用于标识当前数据包的位置,SYN标志为1时,是随机生成的初始序列号ISN,假设为x。

第二次握手:主机B收到主机A数据包后回一个数据包给主机A,主机B状态从LISTEN转为SYN-RECEIVED,本次发送数据包头部有以下特点:

  • ACK标志为1,表示该数据包是回应数据包。
  • 确认号码为x+1,表示该数据包是回应主机A发送的数据包序列号码为x的回应数据包,也就是第一次握手发送的数据包。
  • SYN标志为1,表示请求建立连接。
  • 序列号码用于标识当前数据包的位置,SYN标志为1时,是随机生成的初始序列号ISN,假设为y。

第三次握手:主机A收到主机B回应的数据包后,再回一个数据包给主机B,主机A状态从SYN-SENT转为ESTABLISHED,本次发送数据包头部有以下特点:

  • ACK标志为1,表示该数据包是回应数据包。
  • 确认号码为y+1,表示该数据包是回应主机B发送的数据包序列号码为y的回应数据包,也就是第二次握手发送的数据包。
  • SYN标志为0,表示这不是请求建立连接的数据包。
  • 序列号码用于标识当前数据包的位置,本次握手为x+1。

当主机B收到第三次握手后,状态从SYN-RECEIVED转为ESTABLISHED,三次握手完成。这是建立TCP连接最常见、也是最正常的情况,但是现实中的网络情况错综复杂,并不是每次建立连接都这么理想,按照一问一答这样的顺序来完成,使用三次握手的方式来建立连接,就是为了尽可能的建立正确有效的连接。

参考:TCP协议头部结构

注释

比如说,当主机A向主机B第一次发送建立连接请求时,由于网络延迟导致超时,然后主机A重新尝试,第二次发送建立连接请求,但是还没等第二次请求发送到主机B,第一次发送请求先达了主机B,对于主机B来说,这是第一次接收到连接请求,所以直接回复连接请求,那么主机A收到回复之后会如何处理呢?过程如下图所示。

TCP协议建立连接的过程-三次握手

当主机A接收到主机B的回复时,发现确认号码不是101,而是91,就会回复主机B一个序列号码为91且RST标志为1的数据包,当主机B收到RST数据包后就会从SYN-RECEIVED恢复到LISTEN状态,当第二次发送的序列号码为100的建立连接请求达到主机B后,再从头开始正常的三次握手流程。

如果上面的情况改一下,第二次发送的建立连接请求先达了主机B,并且顺利完成了连接,此时才收到第一次发送的建立连接请求,会发生什么情况呢?过程如下图所示。

TCP协议建立连接的过程-三次握手

当主机B收到一个意外的请求时,因为主机B已经处于ESTABLISHED状态,并且正在接收的这个数据包不在接收窗口之内,此时它只会回复一个包含当前确认号码的数据包,也就是<SEQ=201><ACK=101><CTL=ACK>。

总结

除了上面提到的两种场景,还有很多非正常的场景。上面提到了三次握手是为了尽可能的建立正确有效的连接,试想一下如果只有两次握手,该如何处理各种非正常情况,那为什么不四次握手,我个人觉得四次握手在某些特殊场景下可能比三次握手更有效,但是对于大多数情况而言,三次握手就足够了,多一次握手会增加额外的开销,所以三次握手是综合考虑各种因素的最终选择。

tcp三次握手