为什么TCP连接要三次握手?(互联网公司面试的宠儿)

昨天一个学姐去参加了秋招的提前面试,回来把考官问的问题和我们一起分享了。其中就有一个关于TCP/IP三次握手的问题。感觉想进个一个好点的互联网公司,面试的时候都会涉及这个问题。但是这个问题绝对不是停留在课本知识上的三次握手,考官会把这个问题变着问。个人感觉类似的问题是为了考验应聘者的基础知识是否牢固。

那么问题来了(突然想起一个梗,中国山东找蓝翔),面试官会怎么问这个问题?像我学姐就被问的是:为什么TCP连接是三次握手而不是四次握手?类似的问题还有为什么建立连接的时候不是两次握手?

1.TCP建立连接为什么不是两次握手?&TCP建立连接为什么是三次握手?(这两个问题的答案是一样的)

面试官:从我们学习过的计算机网络可知,服务器在第二次握手的时候就分配好一定的资源用于建立连接,而且客户端第三次握手只是发送一个确认报文(有时第三次握手可以携带数据)。那为什么我们不使用两次握手进行连接?

答:一般回答网络的问题的时候,我都会先提醒自己,网络层是不可靠的。双方在通信的时候,就算是TCP连接,在网络层都有可能丢包,只不过是传输层有处理丢包的策略。若TCP连接是两次握手,那么突然来了一个已失效的客户端连接请求报文,服务器会把这次失效的连接当成正常的连接对待。假设连接过程如下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了(可能是网络延迟),以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的传输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。假如客户端还处于连接状态,当客户端在收到服务器的同步报文后一脸懵逼(我不是连上了吗?怎么还给我发同步报文?我是谁?我在哪?我要干什么?)。采用“三次握手”可以防止上述现象发生。

其实两次握手还有一个不好的地方,就是会更容易受到SYN攻击。我之前把关于三次握手的缺陷的知识做了整理,里面就分析SYN攻击的原理。原本三次握手情况下,服务器在多次等不到客户端的ACK报文后,就会把分配的资源释放掉。现在换成两次握手,由于没有第三次的ACK报文,服务器的资源就会一直被“浪费”。

2.TCP连接为什么不是四次握手?

答:关于这个问题我想过两种情况,在三次握手的基础上,第四次握手应该怎么加?①:因为第三次握手时,客户端已经发送了ACK报文了,所以服务器不会再发同步报文应该也不会发送数据报文,如果发送数据报文,那就不能把这次“握手”划分到连接阶段),而是再发一个ACK报文。这样分析下来,第四次握手完全是没有必要的,因为第三次握手时,客户端已经确认连接了才发送的ACK报文。而此时服务器再去询问客户端你要不要连接不是很怪吗?②:第四次握手加到客户端,相当于客户端发送两个ACK报文确定连接。这种方式就很傻了,我唯一能为这种模式找的借口就是能把服务器分配资源的时间放到两个ACK报文发送的时间间隔中,然后再结合一些安全策略防止SYN攻击等网络攻击(不过一般可以通过代理服务器解决这一问题)。但如果真的用这种四次握手的模式,客户端等待的事件只会更长,因为多发一次报文,就多一点丢失报文的概率,客户端就可能在等待连接上花费更多的时间。

综合分析下来,两次握手不可行的原因:服务器的资源会被白白“浪费”,且容易被黑客攻击。四次握手不可行的原因:不能有效的增加TCP连接的安全性,反而让客户端等待的时间变长,在实际应用中这明显不适用。

猜你喜欢

转载自blog.csdn.net/qq_38289815/article/details/81098906