断开连接四次挥手分为如下四步(假设没有出现挥手合并的情况):
- 第一步,client 端主动发送 FIN 包给 server 端;
- 第二步,server 端回复 ACK(对应第一步 FIN 包的 ACK)给 client,表示 server 知道 client 端要断开了;
- 第三步,server 端发送 FIN 包给 client 端,表示 server 端也没有数据要发送了,可以断开了;
- 第四步,client 端回复 ACK 包给 server 端,表示既然双发都已发送 FIN 包表示可以断开,那么就真的断开了啊 。
文章插图
其中比较难以理解的是 TIME_WAIT 状态,主动关闭的那一端会经历这个状态 。这一端停留在这个状态的最长时间是 Maximum segment lifetime(MSL)的 2 倍,大部分时候被简称之为 2MSL 。存在 TIME_WAIT 状态有如下两个原因:
- 要可靠的实现 TCP 全双工连接终止;
- 让老的重复 segment 在网络中消失(一个 sement 在网络中存活的最长时间为 1 个 MSL,一来一回就是 2 MSL);
网上流传的资料都说 TCP 是双向的,所以回收需要四次,但是握手也是双向(握手双方都在告知对方自己的初始 Sequence number),那么为什么就不用四次握手呢?所以凡事需要多问几个为什么,要有探索和怀疑精神 。
你再仔细回看上面三次握手的第二步(SYN + ACK),其实是可以拆分为两步的:第一步回复 ACK,第二步再发 SYN 也是完全可以的,只是效率会比较低,这样的话三次握手不也变成四次握手了 。
看起来四次挥手主要是收到第一个 FIN 包后单独回复了一个 ACK 包这里多了一次,如果能像握手那样也回复 FIN + ACK 那么四次挥手也就变成三次了 。这里再贴一下上面这个挥手的抓包图:
文章插图
这个图中第二个红框就是 server 端回复的 FIN + ACK 包,这样四次挥手变成三次了(如果一个包算一次的话) 。这里使用四次挥手原因主要是:被动关闭端在收到 FIN 后,知道主动关闭端要关闭了,然后系统内核层会通知应用层要关闭,此时应用层可能还需要做些关闭前的准备工作,可能还有数据没发送完,所以系统内核先回复一个 ACK 包,然后等应用层准备好了主动调 close 关闭时再发 FIN 包 。
而握手过程中就没有这个准备过程了,所以可以立即发送 SYN + ACK(在这里的两步合成一步了,提高效率) 。挥手过程中系统内核在收到对方的 FIN 后,只能 ACK,不能主动替应用来 FIN,因为系统内核并不知道应用能不能立即关闭 。
总结TCP 是一个很复杂的协议,为了实现可靠传输以及处理各种网络传输中的 N 多问题,有一些很经典的解决方案,比如其中的网络拥塞控制算法、滑动窗口、数据重传等 。强烈建议你去读一下 rfc793 和 TCP/IP 详解 卷1:协议 这本书 。
如果你是那些纯看理论就能掌握好一门技能,然后还能举三反一的人,那我很佩服你;如果不是,那么学习理论知识注意要结合实践来强化理解理论,要经过反反复复才能比较好地掌握一个知识,讲究技巧,必要时要学会通过工具来达到目的 。
经验总结扩展阅读
- 【lwip】10-ICMP协议&源码分析
- 医保个人账户余额突然没有了 来分析一下原因
- 【lwip】09-IPv4协议&超全源码实现分析
- 欧莱雅小蜜罐面霜孕妇可以用吗_欧莱雅小蜜罐面霜成分分析
- 概念+协议的了解+OSI七层模型,TCP/IP五层协议,网络数据传输流程 Linux--网络基础
- Redis先操作数据库和先删除缓存, 一致性分析
- 2023年10月17日适合提车吗 黄历宜忌分析
- ysoserial CommonsCollections2 分析
- 未来就业方向前景分析 食品加工技术专业毕业后干什么工作
- 计算机专业就业方向及前景分析