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