TCP 三次握手,四次挥手
TCP 采用三次握手建立连接,采用四次挥手关闭连接。
三次握手的目的是确保双方的收发信息的能力是正常的。
第一次握手,客户端发送SYN,服务端收到,这样服务端得出结论:服务端的接收能力和客户端的发送能力是正常的;
第二次握手,服务端发送SYN+ACK,客户端收到,这样客户端得出结论:服务端的接收、发送能力正常,客户端的发送、接收能力也正常。
第三次握手,客户端发送ACK,服务端收到,这样服务端得出结论:客户端的接收、发送能力正常,服务端的接收和发送能力也正常。
三次握手之后,客户端和服务端都确定了彼此的接收和发送能力是正常的,之后就可以正常通信了。
- 一开始,客户端和服务端均处于
CLOSE
状态,服务端主动监听端口,处于LISTEN
状态- 客户端主动发起连接
SYN
,之后处于SYN_SENT
状态- 服务端收到连接,返回
SYN
,并且ACK
客户端的SYN
,之后处于SYN_RECV
状态- 客户端收到服务端的
SYN
和ACK
之后,发送对SYN
确认的ACK
,之后处于ESTABLISHED
状态- 服务端收到客户端的
ACK
之后,处于ESTABLISHED
状态
四次挥手的目的是为了关闭双工。
第一次挥手,客户端发送 FIN 给服务端,说明客户端不必发送数据给服务器了;
第二次挥手,服务端接收到,回复 ACK,同意释放连接,客户端接收到 ACK,释放连接;
第三次挥手,服务端发送 FIN 给客户端,说明服务端不必发送数据给客户端了;
第四次挥手,客户端收到,回复 ACK,等待 2MSL(2倍的TCP报文生命周期),同意释放连接,服务端接收到 ACK,释放连接。
为什么连接只需要三次,释放连接却需要四次?
因为 TCP 是全双工模式,ACK 和 FIN 是分开发送的,即请求关闭和确认关闭是分开的。但建立连接时,服务器的SYN和ACK是同时发送的,即同意连接和请求连接是同时的,所以连接只需要三次,释放却需要四次。
为什么连接时ACK和SYN可以一起发送,释放时则需要ACK和FIN分开发送呢?
因为客户端请求释放时,服务端可能还有数据需要传输给客户端,因此服务端要先响应客户端FIN请求(服务端发送ACK),然后数据传输完成后,服务端在发送FIN提出FIN请求,而连接时则没有中间的数据传输,因此可以一起发送。
为什么客户端需要等待 2MSL?
因为客户端不知道服务端是否能收到 ACK 数据报,服务端如果没收到,会进行重传,等待的 MSL 与 服务端重传的总时间即为 2 倍的 MSL。