目录
什么是“三次握手” “四次挥手”?
三个标记位
三次握手
四次挥手
为什么握手三次,挥手需要四次?
为什么要等2MSL?
什么是“三次握手” “四次挥手”?
三次握手(Three-way Handshake):其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
四次挥手(Four-way handshake):TCP 连接的拆除需要发送四个包,因此称为四次挥手。
三个标记位
SYN(Synchronize):用于建立连接的初始握手。发送方发送一个SYN报文段给接收方,请求建立连接。
ACK(Acknowledgement):用于确认数据的传输。当成功接收到数据后,接收方发送一个带有ACK标记的报文段回复发送方,确认已经收到了数据。
FIN(Finish):用于关闭连接。当发送方发送完所有数据后,会发送一个带有FIN标记的报文段,请求关闭连接。 接收方在收到FIN报文段后,发送一个带有ACK标记的报文段进行确认,并使用一个定时器在一段时间后关闭连接。
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
三次握手
第一次握手:客户端发送网络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
第三次握手:客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
到此,三次握手的过程就算结束了。最后,当服务器收到客户端的 ACK 报文之后,也处于 ESTABLISHED 状态。此时,连接就已经建立成功了。
四次挥手
第一次挥手:客户端向服务器发送一个FIN(结束)请求,表示客户端不再发送数据。此时客户端处于FIN_WAIT_1状态。
第二次挥手:服务器收到请求后,回复客户端一个ACK响应确认,但这个响应可能还携带有未传输完的数据。此时服务器处于CLOSE_WAIT状态。注意,在第三次挥手之前,数据还是可以从服务器传送到客户端的。
第三次挥手:服务器完成数据传输后,向客户端发送一个FIN请求,表示服务器也没有数据要发送了。此时服务器状态变为LAST_ACK状态。
第四次挥手:客户端收到服务器的请求后,回复服务器一个ACK响应确认。此时客户端处于TIME_WAIT状态,需要经过一段时间确保服务器收到自己的应答报文后,才会进入CLOSED状态。
到这里,四次挥手就已经结束了。最后,服务器收到ACK报文后,就关闭连接,也处于CLOSED状态了。
为什么握手三次,挥手需要四次?
因为当握手时,服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。所以需要四次挥手。
为什么要等2MSL?
为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。