为什么我们需要3次握手?为什么不只是2路?

网络工程 通讯协议 协议理论 第4层 传输协议
2021-07-13 13:02:30

TCP 3 次握手的工作原理如下:

Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server

为什么不只是这个?

Client ------SYN-----> Server
Client <-----ACK------ Server
4个回答

将握手分解为它真正在做什么。

在 TCP 中,双方通过使用序列号来跟踪他们发送的内容。实际上,它最终成为发送的所有内容的运行字节数。接收方可以使用对方说话者的序列号来确认它接收到的内容。

但是序列号不是从0开始的,而是从ISN(Initial Sequence Number)开始的,它是一个随机选择的值。由于 TCP 是双向通信,双方可以“说话”,因此双方必须随机生成一个 ISN 作为他们的起始序列号。这反过来意味着,双方都需要通知对方他们的起始 ISN。

因此,您最终会得到以下事件序列,以开始 Alice 和 Bob 之间的 TCP 对话:

Alice ---> Bob    SYNchronize with my Initial Sequence Number of X
Alice <--- Bob    I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob    SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob    I received your syn, I ACKnowledge that I am ready for [Y+1]

请注意,正在发生四个事件:

  1. Alice 选择一个 ISN 并将其与 Bob同步
  2. Bob确认ISN。
  3. Bob 选择一个 ISN 并将其与 Alice同步
  4. Alice确认ISN。

但实际上,中间的两个事件(#2 和 #3)发生在同一个数据包中。是什么使数据包成为SYNACK只是在每个TCP 标头内打开或关闭的二进制标志,因此没有什么可以阻止在同一个数据包上启用这两个标志。所以三向握手最终是:

Bob <--- Alice         SYN
Bob ---> Alice     SYN ACK 
Bob <--- Alice     ACK     

注意“SYN”和“ACK”的两个实例,两个方向各一个。


那么回到你的问题,为什么不使用双向握手呢?简短的回答是因为双向握手只允许一方建立 ISN,另一方确认它。这意味着只有一方可以发送数据。

但是 TCP 是一种双向通信协议,这意味着任何一端都应该能够可靠地发送数据。双方都需要建立一个ISN,双方都需要确认对方的ISN。

所以实际上,你所拥有的正是你对双向握手的描述,但在每个方向上因此,发生了四个事件。同样,中间的两个标志出现在同一个数据包中。因此,在完整的 TCP 连接启动过程中涉及三个数据包。

因为双方都需要的三次握手是必要的SYN chronize其传输过程中所使用的部分序列号。为此,他们每个人(依次)发送一个序列号设置为随机值n的 SYN 段,然后另一方通过序列号设置为n+1的 ACK 段确认该段

为了使连接正常工作,每一方都需要验证它是否可以向另一方发送数据包。确保您将数据包发送到另一端的唯一方法是从他们那里获取数据包,根据定义,除非您发送的数据包通过,否则不会发送该数据包TCP本质上为此使用两种消息:SYN(请求证明该数据包通过)和 ACK(仅在 SYN 通过后发送,以证明 SYN 通过)。实际上还有第三种消息,但我们稍后会谈到。

在连接开始之前,双方都对对方一无所知。客户端向服务器发送 SYN 数据包,以请求其消息可以通过的证明这不会告诉任何人任何事情,但这是握手的第一步。

如果 SYN 通过,那么服务器就知道客户端可以向它发送数据包,因为它刚刚发生。但这并不能证明服务器可以发回数据包:客户端可以出于多种原因发送 SYN因此,服务器需要向客户端发送两条消息:一个 ACK​​(证明 SYN 通过)和一个 SYN(请求自己的 ACK)。TCP 将这两个消息合并为一个 - SYN-ACK 消息,如果您愿意的话 - 以减少网络流量。这是握手的第二步。

因为 SYN-ACK 是一个 ACK​​,所以客户端现在肯定知道它可以向服务器发送数据包。并且因为 SYN-ACK 是一个 SYN,它也知道服务器需要该消息通过的证据。所以它发回一个 ACK​​:这次只是一个普通的 ACK,因为它不再需要证明它的数据包可以通过。这是握手的最后一步:客户端现在知道数据包可以双向传输,并且服务器即将解决这个问题(因为它知道 ACK 将通过)。

一旦该 ACK 通过,现在服务器知道它可以向客户端发送数据包它还知道客户端知道这一点,因此它可以立即开始发送数据。握手完成。我们有一个很好的渠道。

嗯,严格来说,我们不能确定我们有一个好的渠道仅仅因为这一系列数据包通过并不能严格保证其他人会通过。我们无法证明,如果不发送无限数量的 SYN 和 ACK,那么其他任何事情都不会完成,所以这不是一个真正可行的选择。但在实践中,三个步骤对于大多数用途来说已经足够了

实际上,3 次握手并不是建立 TCP 连接的唯一方法。也允许同步 SYN 交换:http : //www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm

这可以看作是一种双向的双向握手。