查看: 624|回复: 0
打印 上一主题 下一主题

[经验] 8 Linux 网络编程 TCP 协议(断开连接)

[复制链接]

该用户从未签到

跳转到指定楼层
楼主
发表于 2021-4-22 13:07:53 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
分享到:
这一篇,讨论的是著名的四次挥手。

1. 断开连接
在此之前,先看图 1,看看 TCP 是如何断开连接的.


图1 四次挥手

图 2,仍然是之前的实验中所抓取的数据包,你可以以在 unp/protocol/data/tcp_retrans.pkt 目录下找到它。

图2 抓取到的数据包

(1) 首先,由客户端调用 close,将这一端称为主动关闭(active close)。然后该端发送一个 FIN 段到对端。

(2) 接收到 FIN 段的服务器执行被动关闭(passive close)。接下来,接收到此 FIN 段的服务器回复 ACK 进行确认(实际上是由内核自动完成回复的),同时内核会传递一个文件结束符 EOF(放在缓冲区末尾) 给应用进程。

(3) 一段时间后……服务器端也没有数据要发送给对端了,调用 close,这导致服务器端也发送一个 FIN 段到对端。

(4) 客户端接收到 FIN 后,回复 ACK 进行确认。

上面的 4 个步骤就是著名的 4 次挥手。

注意:

执行主动关闭的一方既可以是客户端,也可以是服务器,这两者之间是对等的。
通常断开连接需要 4 个 TCP 段。但是有时候不一定是这样。某些情况下,步骤 1 中的 FIN 段会随着数据一起发送到对端;另一种情况,步骤 2 和步骤 3 有可能被合并成一个 TCP 段(实际抓包中,也遇到了这个情况,如图 3)。

图3 有时候会出现三次挥手的情况

2. 为什么是四次挥手
正好图 3 中所示,完全可以三次挥手就可以断开连接,为什么还要四次挥手呢?

实际上,这是 TCP 的半关闭(half-close)特性所造成的。

因为 TCP 连接是全双工的(数据在两个方向上可以同时传递,图 4),因此每个方向就必须能够单独的关闭。就比如客户端执行了半关闭操作后,只是通知服务器它没有数据要发送了,并不代表它不能接收数据。因此,只要服务器还没有主动关闭,就能够向客户端继续发送数据。也就相当于在步骤 2 和 步骤 3 之间,服务器仍然能够向客户端发送数据。

图4 TCP 连接是全双工的

四次挥手为被动关闭的一方提供了很大的伸缩空间,让被动关闭一方有机会继续向主动关闭一方发数据。**如果**TCP 协议标准要求步骤 2 和 步骤 3 合并成一个步骤,这种伸缩空间就没有了,也就是说只要有一端关闭了,另一方就没有机会继续发送数据。

【注意】

在 Linux 编程学习笔记中讲网络编程的时候,我们关闭连接用的都是函数 close. 任何一端使用函数 close 进行关闭,实际上就直接把全双工两个方向的连接全部关闭了(图 4 中的蓝色通道和红色通道)。如果只想关闭一端,只能使用函数 shutdown 来关闭一个方向的连接。关于 shutdown 函数,将在后续文章中介绍。

实际上,在图 4 中,进程 A 既可以关闭蓝色通道,也可以关闭红色通道,也可以将蓝色通道和红色通道全部关闭,这由 shutdown 的参数控制。也就是说,进程 A 既可以告诉对方我没有数据要写了,也可以告诉对方,它不想读数据了。

3. 总结
掌握四次挥手过程
理解为什么是四次挥手

回复

举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 1/5 下一条

有奖活动|英飞凌智能座舱直播活动
3月12日,英飞凌将携手大联大品佳集团,从行业痛点出发,结合最新技术发展,深入解析智能座舱的技术革新与未来趋势,现场还会有嘉宾为您提供一对一答疑服务。无论您是科技爱好者、工程师,还是投资者与行业分析师,这场直播都将为您揭开智能座舱的核心技术密码!

查看 »



手机版|小黑屋|与非网

GMT+8, 2025-5-6 06:20 , Processed in 0.164013 second(s), 33 queries .

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.5

Copyright © 2001-2024, Tencent Cloud.