查看原文
其他

万兆网速,为何TCP依然需要三次握手?

脚本之家 2022-04-23

The following article is from 车小胖谈网络 Author 车小胖谈网络

 关注
脚本之家
”,与百万开发者在一起

出处:车小胖谈网络(ID:chexiaopangnetwork)

如若转载请联系原公众号

网络情况良好的话TCP/IP协议为什么需要三次握手?
网络上的解释:恩,那么网络良好没有丢包和延时的话是否需要三次握手呢?
为什么不用两次握手?
1.当因为网络原因一个请求滞留在网络中,然后重新发送一个并连接完成关闭后,原来那个请求再次发送给服务器再次建立连接而浪费资源
2.当服务器返回的确认请求丢失了,服务器以为连接已经开始,一直发数据,但是客户端等着确认包,不会接受数据,(网传会死锁,一段时间后重新发送同步请求,按理说也不会死锁)(问题来了,三次握手难道不存在这个问题么,凭啥你三次握手可以自动接收数据两次不行)
如果三次握手的第三个包丢失了
1.客户端进入已连接状态,可能会发送数据包,服务器收到数据包会自动切换到已连接状态。
2.但是服务器发不了数据,会一直超时重传第二个包来等待客户端的确认报文。
 


电脑是如何知道网络状态良好的?
电脑在没有网络测量的前提下,是无法预知网络状况的是网络状况的。如果电脑有先知先觉的能力,还要三次握手、两次握手。想发数据给服务器的时候,直接将数据扔给服务器,这个行为有一个专业名词,0 RTT
 
0次握手
0 RTT的情况下,数据请求从客户端发出开始计时,到请求的数据从服务器返回为止,需要多久?
 
1 RTT。
 
三次握手
古典的TCP三次握手,从握手开始,到握手完成,直到客户端请求的数据从服务器返回为止,需要多久?

1.5 RTT(握手) + 1 RTT(数据往返) = 2.5 RTT。
 
一般来说,比较积极的TCP在第三次握手的时候,已经顺便携带了数据请求,需要的事件将减小为:
 
1 RTT(握手) + 1 RTT(数据往返) = 2 RTT。
 
两次握手
如果采用两次握手,即服务器收到客户端的握手,发出自己的握手信号,即认为握手完成。从握手开始,到握手完成,直到客户端请求的数据从服务器返回为止,需要多久?
 
1 RTT(握手) + 1 RTT(数据往返) = 2 RTT。
 
啊,怎么会这样?两次握手与三次握手,客户端所等待的时间竟然是相同的,都是2 RTT,真的没有想到!
 
同学们会说,不是这样子的!服务器可以在第二次握手的时候,同时携带数据的,那么用户所等待的时间将减小为:1 RTT(握手 + 数据返回)。
 
服务器在没有收到客户端数据请求的情况下,返回什么数据给客户端呢?

没法返回,因为服务器不知道客户端真正感兴趣的数据到底是什么!
 
所以,三次握手与两次握手并没有区别。接下来的问题是,为何当初TCP设计者不采用0次握手?
 
0次握手,可以选择UDP。
 
UDP尽管可以,但是它不确认数据,无法保证数据的可靠传输。
 
我的意思是,依然采用TCP三次握手,依然采用TCP确认机制,客户端第一个握手报文,携带请求数据,那么这和0次握手应该是一样的,获得数据的延迟依然是 1 RTT。这样可以吗?
 
当然可以。但是在TCP/IP诞生的年代,带宽是稀缺资源。在不知道服务器死活的情况下,贸然将数据请求发到网络管道里,是不负责任的行为。
 
而采用三次握手,握手报文本身的尺寸较小,对带宽的影响也比较小。一旦完成三次握手,至少说明服务器他老人家活蹦乱跳,就可以将大尺寸的数据报文发过去了。
 
随着网络带宽的指数级的增长,实现0 RTT的数据传输呼声越来越高。这样的传输协议也相应诞生了,比如QUIC协议。但是这个协议是使用UDP传输的,且第一次无法0 RTT。因为需要认证、协商密钥等参数。但是从第二次起,就可以 0 RTT了,因为密钥等信息依然缓存在客户端、服务器上,也不怕不怕DOS攻击了。
 
随着互联网的爆发式增长,TCP设计的漏洞就成为了攻击的对象。比如伪造TCP SYN握手报文攻击,服务器不分青红皂白开辟内存来保存连接,很快就会耗光内存从而拒绝服务。如果TCP使用0 RTT,攻击更简单,使用更少的报文就可以将服务器的内存耗尽,因为携带数据的报文,比握手报文要大好多倍。
 
为了抵御此类的DOS攻击,服务器的TCP使用CookieOption,服务器收到客户端第一次握手,礼貌性地回复一个“SYN + ACK + Cookie Option“,仅此而已,分配内存吧?
 
不。
 
如果收到客户端的“ACK + Cookie Option“,且这个Cookie Option没错,此时服务器才着手分配内存,标记连接建立。
 
如果客户端的ACK没有携带Cookie Option,或者Cookie Option不对,对不起直接Reset。

-- End --

带你一探德累斯顿晶圆厂  推荐阅读:漫话:如何给女朋友解释为什么Java线程没有Running状态?
送命题,选 C++ 还是 Java?
运行 Java、Python、Go 等 25 种代码后,发现性能最强的竟然是它!
『图解Java并发』面试必问的CAS原理你会了吗?
4月份Github上最热门的Java开源项目

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存