三次握手
复习
- TCP 为什么需要连接:可靠传输需要双方维护并同步状态
- 端口:用 IP 与端口共同标识通信端点
- UDP:无连接,不维护任何通信状态
TL;DR
- 三次握手让双方确认彼此的收发能力
- 同时交换并确认各自的初始序号
- 需要三次而不是两次,是为了防止旧的请求造成误连接
- 握手完成,连接才算真正建立
正文
上一章说,建立连接就是双方对齐状态。具体怎么对齐?这就是著名的三次握手(three-way handshake)。
三步走
过程可以简化成三句话:
- 客户端发一个 SYN:“我想连你,我的初始序号是 x。”
- 服务器回一个 SYN + ACK:“收到,我同意。我的初始序号是 y,也确认你的 x。”
- 客户端再回一个 ACK:“收到你的 y,我们开始吧。”
三步过后,双方都拿到并确认了对方的初始序号,也都确认了“我发的你能收到,你发的我也能收到”。状态对齐,连接建立。
为什么不是两次
这是最经典的问题:既然一来一回就能确认双方收发正常,为什么还要第三次?
关键在于防止“迟到的旧请求”造成错误连接。
设想一个很久以前发出、却被网络耽搁的旧 SYN,这会儿才姗姗来迟地到达服务器。如果只握手两次,服务器收到它、回一个确认,就单方面认为连接建立了,开始等待数据——可客户端根本没想连,于是服务器白白占用资源,等一个永远不会来的对话。
有了第三次,情况就不同:客户端收到服务器的确认后,会发现“我根本没发过这个请求”,于是不理它。服务器收不到第三次,就知道对方并不想连,连接不会真正建立。 这第三次,起到了确认“这次握手确实是当前双方都认的”的作用。
它到底确认了什么
换个角度总结,三次握手其实确认了三件事:
- 客户端能发、服务器能收
- 服务器能发、客户端能收
- 双方就初始序号达成了一致
而初始序号为什么不能固定从 0 开始?主要是为了避免与网络上残留的旧数据包发生混淆。序号从随机值起步,能让每次连接的数据都“对得上号”。
连接建好了,接下来就可以安心传数据了。可靠传输的细节,从“序号与确认”开始。
思考题 1
为什么两次握手不够,必须要有第三次?
思考题 2
三次握手到底确认了哪几件事?
小结
知识点
- 三次握手:SYN、SYN+ACK、ACK
- 它同步双方的初始序号与收发能力
- 第三次可防止迟到的旧请求造成误连接
- 初始序号取随机值,避免与旧包混淆
参考资料
- Wikipedia(zh):传输控制协议:包含连接建立与状态管理
- Wikipedia(zh):握手 (技术):通信双方协商建立连接的过程
思考题答案(仅供参考)
思考题 1
因为要考虑迟到的旧连接请求。只握手两次时,服务器收到一个迟到的旧 SYN 就可能误以为要建立连接,白白等待。加上第三次,客户端面对自己没发过的请求会不予理睬,服务器收不到第三次,就不会建立无效连接。
思考题 2
它确认了:客户端能发且服务器能收、服务器能发且客户端能收,以及双方就各自的初始序号达成一致。这三件事齐备,可靠传输所需的状态才算对齐。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪