TCP为什么采用三次握手,两次握手不行么
假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是再某个网络结点长时间滞留,以致延误到连接释放以后的某个时间才到B 点。本来这就是一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误认为是A 又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。
由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却认为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样浪费了。
采用三次握手的办法可以防止上述现象的发生。例如刚才的情况,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要求建立连接。
为什么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报文段后 立即关闭,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常步骤进入CLOSED状态。
第二,防止上一节提到的“已失效的连接请求报文段”出现在本连接中。A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
为什么连接需要三次,而分开需要四次
因为TCP连接是全双工的(即数据可在两个方向上同时传递)所以进行关闭时两个方向都要单独进行关闭。
当收到对方的FIN报文通知时,它仅表示对方没有数据发送给你了;但是未必你的多有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET