为什么是三次握手?

763 阅读5分钟

本篇文章是线下面对面二人知识分享整理。文中并不会将所讲到点一一展开而是围绕主题选择性展开一部分内容。

三次握手

如果你比较熟悉 TCP 协议,会知道它是一种面向连接的协议,当通信双方连接建立成功后可以开始收发数据了。

这里的连接指的是什么呢?我觉得陈皓在文章中讲的特别好:

TCP 所谓的“连接”,其实只不过是在通讯的双方维护一个“连接状态”,让它看上去好像有连接一样。所以,TCP 的状态变换是非常重要的。

既然收发数据的前提是双方建立连接,那 TCP 是如何建立连接的呢?答案其实就是通过三次握手,图示来自极客时间——《趣谈网络协议》:

三次握手

三次握手建立连接的过程中,会协商出本次通信数据包的初始序号(通过这个序号来保障后续收到数据包不会乱序,且如果有上一次走丢的包也不会被误收)。

由于 TCP 本身是双向通信的,那既然是双向通信,就要确认双方数据收发的能力,这个确认过程就是通过三次握手时完成的,我认为正是这个彼此确认的过程构成了完整的三次握手,同时也揭示了为什么是三次。

下面就来看看这个过程是怎么完成的:

过程中可以通过表格很好的看到双方的确认过程,而最初没有建立连接时,表格空空如也。

对于客户端 客户端 服务端
发送能力
接受能力
对于服务端 客户端 服务端
发送能力
接受能力

当第一次握手的时候,由客户端发送客户端的 SYN,这时客户端并不知道自己发出去数据对方能不能收到,所以暂时上面的表格都是空的。

当服务端接收到客户发来的第一个握手数据包时,它不仅收到了 SYN 带来的序号,而还确认了自己接收数据包的问题时没问题,而且对方发送的能力时没问题,所以对于服务端的表格来说是可以更新的:

对于客户端 客户端 服务端
发送能力
接受能力
对于服务端 客户端 服务端
发送能力 确认没问题
接受能力 确认没问题

这时服务端会为了响应客户端的握手数据包,会返回自己的产生的的序号和对于客户端的 ACK,也就是应答数据包,然后服务端就开始自己的等待了。

接下来顺利的话,客户端会收到服务端的应答包,而收到这个应答包自己就安心多了,因为此时客户端知道了自己的发送能力和接受能力是 ok 的,因为数据包一来一回已经完成了,而对于客户端来说服务端的发送能力和接收能力也是 ok 的,因为对方不仅收到了包还返回了应答,所以此时对于客户端说表格是可以更新的:

对于客户端 客户端 服务端
发送能力 确认没问题 确认没问题
接受能力 确认没问题 确认没问题
对于服务端 客户端 服务端
发送能力 确认没问题
接受能力 确认没问题

其实到这里两次握手的一来一回对于客户端来说已经足够了,因为它完全确认了自己的和对方的收发能力都是 ok 的,但是对于服务端来说其实并没有完成,因为它还不知道自己的发送能力和对方的接收能力到底是否可行,所以这时还需要客户端做一次“应答的应答”,也就是第三次握手,这时它发出握手流程的最后这个“应答的应答”数据包后。

服务端接收成功后,服务端知道自己发出去的包被客户度响应了,并且自己成功收到了这个包,也就说明自己的发送能力是没问题的,而且对方的接收的能力也是没问题。所以此时对于服务端说表格是可以更新的:

对于客户端 客户端 服务端
发送能力 确认没问题 确认没问题
接受能力 确认没问题 确认没问题
对于服务端 客户端 服务端
发送能力 确认没问题 确认没问题
接受能力 确认没问题 确认没问题

那么到这里,恭喜,三次握手完成,确认双方收发能力过程完成,双方数据包序号确认完成,可以开始正式的通信了。

总结

我认为三次握手的三次主要是为了双方确认自己和对方数据收发能力,而两次还不能完成,四次又显得多余,所以三次是一个最好的选择。

其实哪怕第三次的包丢了,但是后续客户端数据上来了,服务端也会觉得双方发送接收能力都是 ok 的。

感谢与参考

一篇搞懂TCP的三次握手 四次挥手

TCP 的那些事儿(上)

第11讲 | TCP协议(上):因性恶而复杂,先恶后善反轻松

最后的最后

如果你觉得我写的还不错的话,那就通过点赞,点赞,还 tm 是点赞的方式给我反馈吧,感谢你的支持。