发布时间:2024-12-16 12:01
网上关于这个问题吵得很凶,但是仔细看过之后我更偏向认为两种说的是一样的。
首先我们来看看 TCP 协议的三次握手过程
如上图所示:
解释一下里面的英文:
三报文挥手的过程如下:
随后,服务器收到了客户端的3,那么就开始进入已建立状态,通信开始了。
简单来说,三个报文分别是,请求-请求确认-请求确认确认(禁止套娃)
原因一:主要是防止客户端发出的已经失效的连接请求报文段,又发送到了服务器,从而导致错误,白白浪费资源。
具体情况是,如果只有两报文握手:
这种说法也来自于《计算机网络的课本》:
“已失效的连接请求报文段” 的产生在这样一种情况下:client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。
本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。
假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。
原因二:这种说法来自于对 RFC 的官方文档说法的解读。
因为TCP 设计中一个基本设定就是,通过TCP 连接发送的每一个包,都有一个sequence number。而因为每个包都是有序列号的,所以都能被确认收到这些包。确认机制是累计的,所以一个对sequence number X 的确认,意味着 X 序列号之前(不包括 X) 包都是被确认接收到的。
TCP 协议不限制一个特定的连接(两端 socket 一样)被重复使用。所以如果一条连接突然断开重连后,TCP 怎么样识别之前旧链接重发的包?
——这就需要独一无二的 ISN(初始序列号)机制。那么这个机制具体实现利用了时钟blabla生成这个可以认为是独一无二的 ISN,那么例子就是:
其实对应到上面的三次握手示意图,也是一样的东西。最后得出结论:
A three way handshake is necessary because sequence numbers are not tied to a global clock in the network, and TCPs may have different mechanisms for picking the ISN's. The receiver of the first SYN has no way of knowing whether the segment was an old delayed one or not, unless it remembers the last sequence number used on the connection (which is not always possible), and so it must ask the sender to verify this SYN. The three way handshake and the advantages of a clock-driven scheme are discussed in [3].
第一句话翻译就是,因为 seq 这个东西,并不是和网络中的全局时钟绑定的,并且 TCP 协议实现这个初始序列号 ISN 的机制有很多种,所以三次握手是必须的。(?)
第二句话翻译就是,第一个接收方,假如我们说是服务器,没办法知道这个报文段是不是 old delayed ,除非记住上一次的seq,然而并不总是可能的,所以必须服务器发给发送端一个报文去判别这次的报文段。那我们结合上面的这个例子
这句话意思就是,服务器接收了,还要把发送确认过去,再让对方确认。
如果没有第三次握手,也就是说上面的四个步骤就只用省略为 1) 2)3),连接直接建立成功。
发现点什么了吗……到这里的问题和谢希仁老师课本里所讲的那种情况其实是一样的啊,因为没有第三次握手的确认,导致连接成功了,而这种时候可能接收方收到的确实就是之前 old delayed 的报文……
所以,吵什么吵,今天我们之所以团聚在这里。。。。