TCP四次挥手

概述

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用 四次握手 断开连接

参见 TCP报头格式

四次挥手

特点

由于TCP连接是 全双工 的,因此,每个方向都必须要 单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个 FIN 来终止这一方向的连接,收到FIN只是意味着 不会再收到数据 了,但是在这个TCP连接上仍然能够 发送数据,直到这一方向也发送了FIN。

四次挥手(Four-Way Wavehand),指断开TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。
在socket编程中,这一过程由 客户端 或 服务端 任一方 执行close来触发

第一次挥手

主动方发送数据包,控制位FIN=1,序号seq=u(u是前面发送数据包的序号加1)。
进入FIN_WAIT_1状态

之前主动方和被动方状态都是ESTABLISHED

第二次挥手

被动方收到数据包后,发送确认包,确认号ack=u+1,序号seq=v(被动方上一次发送数据包的序号加1)
进入CLOSE_WAIT状态
注意:
此时,主动方到被动方,不会发送数据
被动方到主动方的连接并未关闭,仍然可以发送数据

http://www.malaoshi.top/upload/0/0/1EF2ZIICvKVp.png

客户端收到数据包后,进入FIN_WAIT_2状态,等待服务器发送关闭连接的报文

第三次挥手

当被动方没有要发送的数据时,发送关闭连接数据包,控制位FIN=1,序号seq=w(在关闭前可能还会发送一些数据包,所以序号不一定是上面的v+1)
进入LAST_ACK状态

第四次挥手

主动方收到数据包后,发送确认包,控制位ACK=1,确认号ack=w+1,序号seq=u+1
进入TIME_WAIT状态

等2MSL后才能返回到CLOSED状态

总结

TCP连接的结束是四次挥手的过程,ACK一直等于1

序号 方向 序号 确认号 FIN ACK
1 主动方-被动方 80000 90000 1 1
2 被动方-主动方 70000 80000+1=80001 0 1
3 被动方-主动方 75000 80001 1 1
4 主动方-被动方 80001 75000+1=75001 0 1

问题

为什么关闭连接是四次握手

  1. 关闭连接时,当收到主动方的FIN报文通知时,表示主动方没有数据发送了;
  2. 但被动方可能还有数据要发送给对方,所以不能马上断开连接,还需要发送一些数据
  3. 然后被动方发送FIN报文,表示没有数据发送给对方,可以断开连接了

什么是MSL?

见https://www.malaoshi.top/show_1EF3OBDZRURN.html

为什么要等待2MSL?

网络是不可靠的,等待 2MSL 时间主要目的是怕最后一个 ACK 没收到。当被动方没有收到第四个包时,会向主动方重复发送FIN报文,所以主动方不能立即关闭
直到2MSL,主动方都没有再次收到FIN,那么主动方就认为ACK已经被成功接收,则断开连接

如果我们设置的时间少于 2MSL ,旧的连接刚刚关闭,这个时候有新连接进来了,而之前的连接还有残留报文在网络上,就会干扰新的连接的使用。

感谢:
https://www.cnblogs.com/zmlctt/p/3690998.html
https://blog.csdn.net/wn_hello/article/details/50066339
https://blog.csdn.net/yeweilei/article/details/79279963


原文出处:/show_1EF3J4lhAdHn.html