面试问题之计算机网络:TCP三次握手四次挥手
转载于:https://www.cnblogs.com/Andya/p/7272462.html
TCP三次握手:
起初A和B都处于CLOSED关闭状态
B创建TCB,处于LISTEN收听状态,等待A请求
第一次握手:A创建TCB,发送连接请求,进入SYN-SENT同步已发送状态
第二次握手:B收到连接请求,向A发送确认和连接请求,进入SYN-RCVD同步收到状态
第三次握手:A收到B的确认和 连接请求后,向B发出确认,A进入ESTABIISHED已连接状态。
B收到A的确认收进入ESTABLISHED已连接状态。
TCP四次挥手:
起初A和B处于ESTABLISHED状态
第一次挥手:A发出连接释放报文段并处于FIN-WAIT-1终止等待1状态;
第二次挥手:B发出确认报文段且进入CLOSE-WAIT关闭等待状态;
A收到B的确认后,进入FIN-WAIT-2终止等待2状态,等待B的连接释放报文段;
第三次挥手:B没有要向A发出的数据,B发出连接释放报文段且进入LAST-ACK最后确认状态;
第四次挥手:A发出确认报文段且进入TIME-WAIT时间等待状态;
B收到确认报文段后进入CLOSED状态
A经过等待计时器时间2MSL后,进入CLOSED状态。
相关问题:
(1)为什么A还要发送一次确认呢?可以二次握手吗?
答:主要为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。如A发出连接请求,但因连接请求报文丢弃而未收到确认,于是A再重传一次连接请求。后来收到了确认,建立连接。数据传输完毕后,就释放了连接,A共发出了两个连接请求报文段,其中第一个丢失,第二个到达了B,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达B,此时B误认为A又发出了一次新的连接请求,于是向A发出确认报文段,同意建立连接,不采用三次握手,只要B发出确认,就建立新的连接了,此时A不理睬B的确认且不发送数据,则B一直等待A发送数据,浪费资源。
(2)为什么Server端易受到SYN攻击?
服务端的资源分配是在第二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪范攻击,SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
防范SYN攻击措施:降低主机的等待时间使主机尽快的释放连接的占用,短时间受到某IP的重复SYN则丢失后序请求。
(3)为什么A在TIME-WAIT状态必须等待2MSL的时间?
MSL最长报文段寿命MAXinum segment Lifetime,MSL=2,超过这个时间报文会被丢弃
答:两个理由
1)保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,使得处于LAT-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状态。
2)防止“已失效的连接请求报文段”出现在本连接中。A在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
(4)为什么连接的时候是三次握手,关闭的时候却是四次挥手
答:因为服务端收到客户端的SYN请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到服务端所有的报文都发送完了,才能发送FIN报文,因此不能一起发送,故需要四次挥手。