Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

三次握手

复习

  • TCP 为什么需要连接:可靠传输需要双方维护并同步状态
  • 端口:用 IP 与端口共同标识通信端点
  • UDP:无连接,不维护任何通信状态

TL;DR

  • 三次握手让双方确认彼此的收发能力
  • 同时交换并确认各自的初始序号
  • 需要三次而不是两次,是为了防止旧的请求造成误连接
  • 握手完成,连接才算真正建立

正文

  上一章说,建立连接就是双方对齐状态。具体怎么对齐?这就是著名的三次握手(three-way handshake)。

三步走

  过程可以简化成三句话:

  1. 客户端发一个 SYN:“我想连你,我的初始序号是 x。”
  2. 服务器回一个 SYN + ACK:“收到,我同意。我的初始序号是 y,也确认你的 x。”
  3. 客户端再回一个 ACK:“收到你的 y,我们开始吧。”

  三步过后,双方都拿到并确认了对方的初始序号,也都确认了“我发的你能收到,你发的我也能收到”。状态对齐,连接建立。

为什么不是两次

  这是最经典的问题:既然一来一回就能确认双方收发正常,为什么还要第三次?

  关键在于防止“迟到的旧请求”造成错误连接

  设想一个很久以前发出、却被网络耽搁的旧 SYN,这会儿才姗姗来迟地到达服务器。如果只握手两次,服务器收到它、回一个确认,就单方面认为连接建立了,开始等待数据——可客户端根本没想连,于是服务器白白占用资源,等一个永远不会来的对话。

  有了第三次,情况就不同:客户端收到服务器的确认后,会发现“我根本没发过这个请求”,于是不理它。服务器收不到第三次,就知道对方并不想连,连接不会真正建立。 这第三次,起到了确认“这次握手确实是当前双方都认的”的作用。

它到底确认了什么

  换个角度总结,三次握手其实确认了三件事:

  • 客户端能发、服务器能收
  • 服务器能发、客户端能收
  • 双方就初始序号达成了一致

  而初始序号为什么不能固定从 0 开始?主要是为了避免与网络上残留的旧数据包发生混淆。序号从随机值起步,能让每次连接的数据都“对得上号”。

  连接建好了,接下来就可以安心传数据了。可靠传输的细节,从“序号与确认”开始。

思考题 1

  为什么两次握手不够,必须要有第三次?

思考题 2

  三次握手到底确认了哪几件事?

小结

知识点

  • 三次握手:SYN、SYN+ACK、ACK
  • 它同步双方的初始序号与收发能力
  • 第三次可防止迟到的旧请求造成误连接
  • 初始序号取随机值,避免与旧包混淆

参考资料

  1. Wikipedia(zh):传输控制协议:包含连接建立与状态管理
  2. Wikipedia(zh):握手 (技术):通信双方协商建立连接的过程

思考题答案(仅供参考)

思考题 1

  因为要考虑迟到的旧连接请求。只握手两次时,服务器收到一个迟到的旧 SYN 就可能误以为要建立连接,白白等待。加上第三次,客户端面对自己没发过的请求会不予理睬,服务器收不到第三次,就不会建立无效连接。

思考题 2

  它确认了:客户端能发且服务器能收、服务器能发且客户端能收,以及双方就各自的初始序号达成一致。这三件事齐备,可靠传输所需的状态才算对齐。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪