TCP三次握手与四次挥手
TCP三次握手过程为什么没有四次握手?为什么不用两次握手?
TCP四次挥手为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
TCP三次握手过程
A向B发送一个SYN请求报文段B收到报文请求后向A发送SYN+ACK报文段,这时TCP服务器进入SYN-RCVD状态A收到B的确认后,还要向B给出确认。发送ACK报文段,A进入ESTABLISHEDZ状态,B收到A的确认后也进入ESTABLISHED状态。
为什么没有四次握手?
在B收到A报文请求中发送的SYN+ACK报文段其实可以拆分为两个报文段。可以先发送一个ACK确认报文段,再发送一个SYN同步报文段,这样就变成了四次握手,但是效果是一样的。
为什么不用两次握手?
这是为了防止已失效的连接请求报文突然又传送到了B,因而产生错误。 如果A发出的第一个请求报文在某些网络节点长时间滞留,以至于延误到连接释放的某个时间点才到达B,这本来是一个早已失效的报文段。但B接到此失效的连接请求报文段后,就误以为是A有一次发出了新的连接请求,于是先B发出确认报文段,同意建立连接。假设不采用报文握手,那么只要B发出确认,新的连接就建立了。 由于现在A并没有发出建立连接的请求,因此也不会发送数据,但是B却一直等待A发送数据,由此造成了很多资源浪费。
TCP四次挥手
数据传输结束后,通信双方都可以释放连接。现在A和B都处于ESTABLISHED状态。A向B发出FIN连接释放报文段,并停止发送数据,这时A进入FIN-WAIT-1状态B收到连接释放报文段后发出ACK确认报文段,B进入CLOSE-WAIT状态。此时A已经没有数据要发送了,但B若要发送,A仍要接受,即从B到A方向的连接并未关闭A收到B的确认后,进入FIN-WAIT-2状态,等待B发出的连接释放报文。若B已经没有要向A发送的数据,则应用程序会通知TCP释放连接。这时B向A发送FIN=1 + ACK报文段。这时B进入LAST-ACK状态,等待A的确认A在收到B的连接释放报文后,必须对此发出确认ACK报文段。然后进入到TIME-WAIT状态,必须经过时间等待器设置的时间2MSL后,才进入到CLOSED状态。
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
这是为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN + ACK报文段的确认。B会超时重传这个FIN + ACK报文段,而A就能在2MSL时间内收到这个重传的FIN + ACK报文段。接着A重传一次确认,启动2MSL计时器,这样,A和B都会正常进入CLOSED状态。如果A在TIME-WAIT状态中不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到A重传的FIN + ACK报文段,因而也不会重传确认报文段。这样,B就无法正常进入CLOSED状态。防止已失效的连接请求报文段出现在本连接中。A在发送完最后一个ACK报文段后,在经过时间2MSL后,就可以使本连接持续的时间内所产生的所有报文段从网络中消失。这样就可以使下一个新的连接中不会出现旧的请求报文段