4次挥手
状态分析
- 客户端ESTABLISHED:连接已经建立,可正常接收发送数据,当前状态下可发起连接释放的请求(第1次挥手)
- 服务器ESTABLISHED:连接已经建立,可正常接收发送数据,当前状态下可接收自客户端发起的连接释放请求
- 客户端FIN-WAIT-1:已向服务端发起连接释放(第1次挥手,FIN=1,ACK=1)后的状态,等待服务端的连接释放确认(第2次挥手)
- 服务端CLOSE-WAIT:接收到客户端发起的连接释放请求(第1次挥手)后,且向客户端发起连接释放确认(第2次挥手,ACK=1)后的状态。等待本地用户(应用程序)的连接释放确认的信号(已完成与客户端的数据传输工作,可以释放连接)
- 客户端FIN-WAIT-2:接收到服务端发来的确认连接释放(第2次挥手)后的状态,继续等待来自服务端的连接释放请求(第3次挥手)
- 服务端LAST-ACK:本地用户(应用程序)确认可释放连接,且向客户端发起连接释放请求(第3次挥手,FIN=1,ACK=1)后的状态,等待客户端的连接释放确认(第4次挥手)
- 客户端TIME-WAIT:接收到服务端的释放连接请求(第3次挥手),且向服务端发起连接释放确认(第4次挥手)后的状态,并等待2个MSL(最长生存时间),预防因第4次挥手未成功,而导致服务端再次向客户端发起FIN报文被下一次连接(新开的程序占用了之前应用相同port)收到。
- 服务端CLOSE:接收到客户端的连接释放确认(第4次挥手)后的状态,连接释放
- 客户端CLOSE:本地用户(应用程序)确认可释放连接,连接释放
为什么需要4次挥手
- tcp是全双工通信,服务端和客服端都能发送和接收数据,且不能单方面完全断开连接。
- 客户端发送FIN:只能断开客户端向服务端方向的连接
- 服务端发送FIN:只能断开服务端向客户端方向的连接
其他知识
- TCP/IP协议栈在设计上,允许任何一方先发起连接释放请求
- 客户端发送ACK后,需要有个TIME-WAIT阶段,等待一段时间后,再真正关闭连接。一般是等待2倍的MSL(Maximum Segment Lifetime,最大分段生存期)
- MSL是TCP报文在Internet上的最长生存时间,每个具体的TCP实现都必须选择一个确定的MSL值,RFC-1122建议是2分钟,可以防止本次连接中产生的数据包误传到下一次连接中(因为本次连接中的数据包都会在2MSL时间内消失了)
特殊的3次挥手
有时候在使用抓包工具的时候,有可能只会看到“3次“挥手,这其实是将第2、3次挥手合并了
- 当服务端接收到客户端的FIN时,如果服务端后面也没有数据要发送给客户端了,服务端就可以将第2、3次挥手合并,同时告诉客户端两件事