TCP协议断开连接的过程-四次挥手

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

所谓四次挥手,指的是在TCP连接断开时需要发送四个数据包,来确保双方都正常断开连接。

TCP协议断开连接的过程-四次挥手

第一次挥手:主机A主动断开连接,向主机B发送一个请求断开的数据包,主机A状态从ESTABLISHED转为FIN-WAIT-1,此后主机A不能再发送数据,但是还可以接收数据,本次发送数据包头部特点如下:

  • FIN标志为1,表示请求关闭连接。
  • 序列号码用于标识当前数据包的位置,假设为u。

第二次挥手:主机B接收到主机A的数据包后回复一个数据包给主机A,主机B状态从ESTABLISHED转为CLOSED_WAIT,此后主机B还可以将剩余没有发送完的数据发送完毕,直到上层应用调用close操作,本次发送数据包头部特点如下:

  • ACK标志为1,表示该数据包是回应数据包。
  • 确认号码为u+1,表示该数据包是回应主机A发送的数据包序列号码为u的回应数据包,也就是第一次挥手发送的数据包。
  • 序列号码用于标识当前数据包的位置,假设为v。

主机A接收到本次挥手的数据包后,主机A状态从FIN-WAIT-1转为FIN-WAIT-2。

第三次挥手:当主机B上层应用调用close操作后,主机B会向主机A发送一个数据包,主机B状态从CLOSED_WAIT转为LAST-ACK,本次发送数据包头部特点如下:

  • FIN标志为1,表示请求关闭连接。
  • ACK标志为1,表示该数据包是回应数据包。
  • 确认号码为u+1,表示该数据包是回应主机A发送的数据包序列号码为u的回应数据包,也就是第一次挥手发送的数据包。
  • 序列号码用于标识当前数据包的位置,本次挥手还是为v。

第四次挥手:主机A收到主机B的数据包后,再回一个数据包给主机B,主机A状态从FIN-WAIT-2转为TIME-WAIT,本次发送数据包头部特点如下:

  • ACK标志为1,表示该数据包是回应数据包。
  • 确认号码为v+1,表示该数据包是回应主机B发送的数据包序列号码为v的回应数据包,也就是第三次挥手发送的数据包。
  • 序列号码用于标识当前数据包的位置,本次是为u+1。

主机A在进入TIME-WAIT之后需要等待2倍最长报文段寿命(Maximum Segment Lifetime)时间后,状态再转为CLOSED,而主机B接收到本次挥手的数据包后,状态直接从LAST-ACK转为CLOSED。最长报文段寿命(MSL)指的是一个TCP数据包在网络上可以存活的最长时间,如果超过这个时间,即使没有送达,这个数据包也会被丢弃。

参考:TCP协议头部结构

注释

第四次挥手时为什么需要等待2MSL的时间再进入CLOSED状态?有如下两个原因。

  • 为了防止历史数据包被新建立的连接收到。比如在本次连接断开后,这两台主机立马又使用和本次连接相同的端口建立新的连接,如果这断开和重新连接中间没有等待时间的话,旧连接中的滞留网络中的历史数据包,还有可能被新连接所接收。
  • TCP协议断开连接的过程-四次挥手
  • 为了确保第四次挥手发送的数据包对方能够接收到,从而使得对方转为CLOSED状态。比如,主机A在第四次挥手发送完回应数据包之后,假如主机B没有接收到,那么主机B会认为它第三次挥手发送的FIN数据包,没有被主机A接收到,那么主机B还会再次发送,如果主机A第四次挥手后没有等待时间,那么主机B重新发送的数据包将无法接收,主机B会停留在LAST-ACK状态,无法正常进入CLOSED状态。

第二次和第三次挥手会不会合并在一起发送?会,而且这也是很常见的情况,也就是说四次挥手可能变成三次挥手。

TCP协议断开连接的过程-四次挥手

当主机A发送FIN数据包到主机B时,正好主机B也处于可关闭状态,那么第二次和第三次握手就可以合并一起发送,在这种情况下,主机A接收到之后状态直接从FIN-WAIT-1转为TIME-WAIT。理论上主机B的ACK数据包是由内核触发的,而主机B的FIN是由上层应用触发,而上层应用有很多方面因素不能立马触发,比如说CPU调度,但是如果ACK能够延迟发送的话,那么第二次挥手的ACK和第三次挥手的FIN就可能合并一起发送,而延迟发送ACK(TCP delayed acknowledgment)这作为一项优化功能已经在TCP协议中实现。

参考:TCP Transport

注释
TCP四次挥手