详解TCP为什么不能是两次握手

Posted 狱典司

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解TCP为什么不能是两次握手相关的知识,希望对你有一定的参考价值。

三次握手的过程

注意不要遗漏全双工下两缓存(读/写缓存)的分配和变量的分配。
CLOSED:表示初始状态。

LISTEN:该状态表示服务器端的某个SOCKET处于监听状态,可以接受连接。

SYN_SENT:这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,随即进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

SYN_RCVD: 该状态表示接收到SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂。此种状态时,当收到客户端的ACK报文后,会进入到ESTABLISHED状态。

ESTABLISHED:表示连接已经建立。


为什么不可以是两次握手?

为了确保链路的可靠性,两次握手的过程并不能确保链路以及可靠的建立。

这时因为C端和S端并不是一方发送之后就可以确认自己可以正常发送,它们之间隔着网络环境,真正能够确认自端可以正常发送需要依靠对端返回的确认,即ACK。

下面具体分析三次握手过程中通信双端的确认状态,?表示未知,表示可以确定没有问题:

第一次握手

客户端: 自己 【发送 ?| 接收 ?】 对端【发送 ?| 接收 ?】

服务端: 自己 【发送 ?| 接收 ✔】 对端【发送 ✔| 接收 ?】

第二次握手:

客户端: 自己 【发送 ✔| 接收 ✔】 对端【发送 ✔| 接收 ✔】

服务端: 自己 【发送 ?| 接收 ✔】 对端【发送 ✔| 接收 ?】

第三次握手

客户端: 自己 【发送 ✔| 接收 ✔】 对端【发送 ✔| 接收 ✔】

服务端: 自己 【发送 ✔| 接收 ✔】 对端【发送 ✔| 接收 ✔】

【例子】

client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server

本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段同意建立连接

假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。

由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了

采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接


为什么不是四次握手?

没有必要,四次也可以但是会产生性能消耗上的增加,即冗余。


SYN洪范攻击

SYN Flood是一种非常危险而常见的DoS攻击方式。到目前为止,能够有效防范SYN Flood攻击的手段并不多,SYN Cookie就是其中最著名的一种。

SYN Cookie是对TCP服务器端的三次握手协议作一些修改,专门用来防范SYN Flood攻击的一种手段。它的原理是,在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区(缓存及相关变量),而是根据这个SYN包计算出一个cookie值。在收到TCP ACK包时,TCP服务器再根据那个cookie值检查这个TCP ACK包的合法性。如果合法,再分配专门的数据区(缓存及相关变量)进行处理未来的TCP连接。

以上是关于详解TCP为什么不能是两次握手的主要内容,如果未能解决你的问题,请参考以下文章

TCP三次握手和四次挥手详解

深入浅出TCP三次握手 (多图详解)

TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手

Wireshark浅析Tcp三次握手

TCP到底有多厉害?

经典面试题—在浏览器中输入URL之后发生了什么?