TCP断开连接为什么要四次挥手?为什么不能三次挥手?
因为服务端接收到客户端断开连接的请求报文时,服务端可能还有数据要发送,要等待服务端把数据发送完了,才能向客户端发起断开连接的请求,此时服务端只能先回复客户端一个ACK报文,告知客户端我已经收到了断开连接的请求,你可以不用重复发送断开连接的请求了,等我把数据发完再通知你我可以断开连接。服务端的ACK和FIN指令必须分开发送,所以需要四次挥手,而不能三次。
TCP断开连接时,客户端发送最后一个ACK给服务端后,为什么要进入TIME_WAIT等待一段时间才能关闭连接?为什么又要等待2MSL?
- 防止延迟的数据段被其他使用相同源地址、源端口、目的地址以及目的端口的 TCP 连接收到;
- 保证 TCP 连接的远程被正确关闭,即等待被动关闭连接的一方收到 FIN 对应的 ACK 消息;
阻止延迟报文
TCP断开连接时,如果客户端在接收到服务端的FIN自己发送完ACK后直接关闭连接,服务端可能没有收到ACK,会超时重传FIN,此时由于客户端已经关闭了连接,如果客户端有新的程序需要向该服务端的同一个端口传输数据,会重新建立TCP连接,并且这个新TCP连接无法和上一个关闭的TCP连接区分开来,因为源IP地址、源端口、目标IP地址、目标端口都一样,此时新连接传输数据过程中如果收到上次连接的传来的FIN,新连接的状态就异常了,新连接SYN握手会失败,服务端会发送RST阻止客户端连接的建立,因为旧的连接并没有关闭。。也有可能会收到其他服务端发送的报文。
保证连接关闭
服务端发送FIN报文后,如果没有接收到ACK会超时重传FIN,直到收到ACK了才会关闭连接。服务端要等待什么时候超时重传呢?服务端发送FIN后,最多经过一个MSL到达客户端,客户端发送ACK最多经过一个MSL到达服务端,所以服务端等待2MSL没有收到ACK就重发FIN报文,FIN报文最多经过一个MSL到达客户端,所以从客户端发送ACK给服务端要至少等待2MSL,以取保服务端收到了自己发送的ACK,不会超时重传FIN
为什么TIME_WAIT要等待2MSL?
MSL(Maximum Segment Lifetime,最大报文生存时间)是指任何报文在网络上存在的最长时间,超过这个时间的报文都会被丢弃。
网络中可能存在来自发送方的报文,接收方收到后需要回ACK,一来一回两个MSL,等待两个MSL可以确保网络中一定不存在报文。
服务端发送FIN后,会计时等待接受ACK,等待的时间大约是一个RTT多一点的时间,也就是2MSL左右,如果FIN没丢失,客户端发送ACK,发送ACK时服务端已经等待了一个MSL左右,如果ACK丢失了,服务端再等待一个MSL,超时未收到ACK,则会重传FIN,FIN再次到达客户端也需要一个MSL左右,这样客户端至少得等待2MSL,以让服务端重传的FIN达到,如果2MSL后没有收到服务端的FIN,说明服务端已经接收到ACK了,服务端已经关闭连接,同时网络也不可能有此次连接的任何报文了,客户端就可以安全的关闭连接。
进入TIME_WAIT有什么问题?
大并发量的短时间传输的连接,会造成连接等待时间变长。