5.TCP协议-断开连接(四次挥手)

本文来自阅读这篇博文并进行了修改:https://blog.csdn.net/q1007729991/article/details/69388961

断开连接


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

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

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

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

注意:

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

为什么是四次挥手

正如上图中所示,完全可以三次挥手就可以断开连接,为什么还要四次挥手呢?

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

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


四次挥手为被动关闭的一方提供了很大的伸缩空间,让被动关闭一方有机会继续向主动关闭一方发数据;

如果TCP 协议标准要求步骤 2 和 步骤 3 合并成一个步骤,这种伸缩空间就没有了,也就是说只要有一端关闭了,另一方就没有机会继续发送数据;

【注意】

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

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

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页