为什么四次挥手是四次,比三次握手多一次

网上搜到的答案多半是文不对题,甚至是错的,比如下面这些:

https://juejin.cn/post/6844903958624878606
https://skrskr66.top/2019/06/13/TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/
https://zhuanlan.zhihu.com/p/128940209

不管怎样都没解释清楚,为什么建立连接需要三次,而断开连接需要四次。

不管是从丢包、稳定性、防错包各种角度,始终无法解释,断开连接的过程为什么比建立连接过程特殊,他们有什么区别,是什么导致断开连接需要多通信一次

三次握手:

用最小的交互次数,满足双方同时知道自己以及对方都具备完整的收包和发包能力。也就是握手最少三次,这一点比较好理解。

四次挥手:

首先看FIN的定义:FIN (1 bit): Last packet from sender

FIN的意思是我方不再朝对方发送包,并不代表关闭连接,也就是说,从语义上来讲FIN并不是SYN的反义。SYN是表示双方建立连接,而FIN仅表示我方不再发包(而不是断开连接)。这一点非常关键,导致了建立连接和断开连接两个过程之间的本质区别。

FIN不需要像三次握手建立连接那样(满足双方同时知道自己以及对方都具备完整的收包和发包能力 ),FIN只需要满足双方都知道其中一方发了FIN,所以实际上比三次握手少一次,也即两次(FIN/ACK),也就是对于其中一方来讲,实际上是两次挥手。

四次挥手,实际上是双方各产生了一个独立的FIN/ACK过程,两次挥手和两次挥手,加起来总共四次。

(实际上两次FIN是可以分开发的,也就是A发了FIN给B,B不一定也要FIN,B还可以一直给A发报文,TCP协议并没有规定一方FIN之后另一方一定得FIN)

下面这篇文章也解释得比较好,全双工的协议需要双方各关闭一次:

为什么要四次挥手
为什么建立一个TCP连接需要三次握手,而终止一个连接需要四次挥手呢?这是因为TCP半关闭造成的。由于一个TCP连接是全双工的,在两个方向上都能传输数据,因此两个方向就需要单独关闭。所以这个流程是这样的:
客户端执行主动关闭,发送FIN报文,告诉服务端,我没有数据要发送了,我要关闭连接,当然了,你有啥数据要给我,我随时候着
服务端收到后,必须及时告诉客户端我收到了,因此先回复客户端一个ACK。但是服务端可能还有未发送完的数据,因此它可以将自己未完成的数据进行发送,发送完成之后,再发送给客户端FIN报文,表明我也没啥要发送的了,关闭吧
客户端收到后,也回复ACK响应,最终关闭连接
因而整个过程需要四次挥手。

https://www.yanbinghu.com/2019/07/14/62738.html

三次握手是一个完整独立的过程,代表连接的建立,不能多也不能少,不能拆分。而四次挥手并不是。四次挥手实际上是发生了两次挥手过程,每次挥手通信两次(FIN/ACK) ,这两次挥手过程是相互独立可以拆分的,可以在一方FIN完之后另一方永远不FIN。三次握手和四次挥手从根本上不能类比。

实际上我认为四次挥手这个概念产生了很大的误导性,让人误以为四次挥手是一个完整的不可拆分的过程。只要是以四次挥手作为一个整体来分析问题的,基本都是错的,永远无法解释清楚为什么握手是三次,而挥手是四次。

结论

建立连接需要双方确认双方都具有收发能力,最少需要三次通信。

断开连接比建立连接要求低,断开连接只需要双方知道某一方发送了FIN,最少只需要两次通信(FIN/ACK)。

所以实际上挥手并不是比握手多一次,而是少一次,是两次挥手。

而因为TCP是全双工协议,意味着双方各需要关闭一次连接,导致两次挥手发生了两次,也就是常说的四次挥手

我宁愿称为三次握手和两次挥手。

发表评论

邮箱地址不会被公开。 必填项已用*标注