TCP建立连接的过程为何是3次而非1次、5次、7次或其他次数
作者:互联网
第一种解释:
假设:存在 A 军、 B 军、 C 军, A 军和 B 军均无法独自战胜 C 军,只有 A 军与 B 军合作才能战胜 C 军。
-
A 军向 B 军发送消息说, A 军将于明早 8 点与 B 军共同进攻 C 军(这是第一条消息)。
此时 A 军会想,假如这条消息 B 军没有收到,那么就只有自己进攻 C 军,势必会输,所以为了 验证 第一条消息 B 军有收到,就需要让 B 军发送一个确认消息证明收到了这条消息。
-
B 军在收到了 A 军所发送的第一条消息后,为了避免上述情况,就会立即给 A 军发送一个确认消息(这是第二条消息)。
此时 B 军会想,假如在中途因为各种原因导致 A 军没有收到第二条消息,那么 A 军就会因为没有收到第一条消息的确认消息进而不会发起进攻,那么也就只有自己会进攻 C 军,势必会输,所以为了 验证 A 军有收到第二条消息,就需要让 A 军发送一个确认消息证明收到了这条消息。
-
A 军在收到了 B 军所发送的第二条消息后,为了避免上述情况,就会立即给 B 军发送一个确认消息(这是第三条消息)。
此时 A 军会想,假如在中途因为各种原因导致 B 军没有收到第三条消息,那么 B 军就会因为没有收到第二条消息的确认消息进而不会发起进攻,那么也就只有自己会进攻 C 军,依旧会输,所以为了 验证 B 军有收到第三条消息,就需要让 B 军发送一个确认消息证明收到了这条消息。
-
B 军在收到了 A 军所发送的第二条消息后,为了避免上述情况,就会立即给 A 军发送一个确认消息(这是第四条消息)。
...
- ...
...
这就是著名的两军问题,可以发现,我们有办法确认第一条消息的送达,却无法确认最后一条消息的送达。而这个确认的过程可以预见是一个无限的过程。而对于 TCP 的三次握手建立连接过程来说,如果只有一次则连第一条消息都无法确认,三次之后再多也没有实际意义,所以三次只是一个折中的数字,这就是为什么 TCP 是三次握手,而非 1 次、 5 次或 7 次。
- 大多描述中所说的如果没有收到哪一个报文就会出现什么什么样的情况,这种解释本质上都是在说两军问题。
第二种解释:
TCP 的三次握手相较于 UDP 来说是在正式发送数据之前发生的一个确认机制。 UDP 不论数据是否能送达目的主机都会直接发送,而 TCP 的三次握手是为了在正式发送数据之前先判断路径是否可达的一个机制。
在客户端发送一个建立连接的请求 SYN 给服务器时,客户端不知道自己能否将数据正常发出、服务器能否成功接收数据,也不知道沿路路径是否通畅。所以此时客户端可以判定的情况如下:
- 客户端 发送
- 客户端 接收
- 服务器 发送
- 服务器 接收
当服务器收到客户端发送的建立连接的请求后发现报文符合协议规范,则可以证明客户端的发送功能正常、服务器的接收功能正常,并且沿路路径通畅。然后服务器要对收到的建立连接的请求报文回复对应的 ACK 确认(seq和ack确保请求和应答的一一对应关系,另一个机制),并同时也将此报文的 SYN 位置 1,表明这个报文也是建立连接的请求。则此时服务器可以判定的情况如下:
- 客户端 发送
- 客户端 接收
- 服务器 发送
- 服务器 接收
当客户端收到回复的 ACK 并发现与自己所发送的 SYN 请求成功配对时,则客户端能够判定:
- 客户端 发送
- 客户端 接收
- 服务器 发送
- 服务器 接收
客户端在收到服务器的 SYN 建立连接请求后,也要回复一个与之对应的 ACK 给服务器,则此时服务器就能够判定:
- 客户端 发送
- 客户端 接收
- 服务器 发送
- 服务器 接收
综上所述,在经历了三次握手之后,客户端与服务器均可判定双方的合法性,并且知道路径通畅是可以发送数据的,然后才能发送数据。所以说 1 次握手完成不了这些校验, 3 次足矣, 5 次或 7 次则完全没有必要。
我的理解:
- 三次握手对于保证 TCP 连接的可靠性来说只是其中的一个机制,是其中一环,不存在 TCP 连接的可靠性是由三次握手提供的这种说法。
- 是由拥塞控制、四次挥手、SYN和ACK、SACK、Nagle算法、延迟确认等等的机制共同互相配合共同确保了 TCP 连接的可靠性与性能优化。
标签:收到,TCP,发送,次数,消息,服务器,接收,连接,客户端 来源: https://www.cnblogs.com/juzi2333/p/16483247.html