第一次挥手:客户端发送一个FIN为1,序列号随机生成的报文给服务器(假设序列号为M),进入FIN_WAIT_1状态;
第二次挥手:服务器收到这个报文之后,发送一个ACK为1,acknowledge number=M+1的应答报文给客户端,进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
第三次挥手:服务器发送一个FIN为1,序列号随机生成的报文给客户端(假设序列号为N),进入LAST_ACK状态;
第四次挥手:客户端收到服务器的FIN报文后,进入TIME_WAIT状态;接着发送一个ACK为1,acknowledge number=N+1给服务器;服务器收到后,确认acknowledge number是否为N+1,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
应为服务器收到客户端的FIN报文时有可能还没有做好断开连接的准备(如还有部分数据没有发给客户端,还在继续发送),但需要先发送一个ACK报文告诉客户端我收到了断开连接的请求,等服务器准备好了,再发一个FIN报文给客户端,告诉客户端可以断开连接了。
由于客户端没有收到ACK报文,客户端会继续发送FIN报文给服务器
因为客户端给服务器发送的ACK报文可能会丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果服务器没有收到ACK报文,就会重发FIN,如果客户端在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止服务器没有收到ACK而不断重发FIN。
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,客户端都没有再次收到FIN,那么客户端推断ACK报文已经被成功接收,则结束TCP连接。
服务器收到客户端的FIN报文时,已经准备好了断开连接(没有数据要发送了)+开启了捎带应答,就可以讲ACK报文和FIN报文合并发送,变为三次挥手
当发送没有携带数据的 ACK,它的网络效率也是很低的,因为它也有 40 个字节的 IP 头 和 TCP 头,但却没有携带数据报文。
为了解决 ACK 传输效率低问题,所以就衍生出了 TCP 延迟确认。
TCP 延迟确认的策略:
当有响应数据要发送时,ACK 会随着响应数据一起立刻发送给对方
当没有响应数据要发送时,ACK 将会延迟一段时间,以等待是否有响应数据可以一起发送
如果在延迟等待发送 ACK 期间,对方的第二个数据报文又到达了,这时就会立刻发送 ACK
作者:今天也是敲代码的一天哦
原文链接:https://blog.csdn.net/weixin_54575205/article/details/127269159