既然我们已经讲解到了这里,那么索性把数据收发完成后协议栈要执行的操作也讲一讲吧。这样一来,从创建套接字到连接、收发数据、断开连接、删除套接字这一系列关于收发数据的操作就全部讲完了。

毫无疑问,收发数据结束的时间点应该是应用程序判断所有数据都已经发送完毕的时候。这时,数据发送完毕的一方会发起断开过程,但不同的应用程序会选择不同的断开时机。以Web为例,浏览器向Web服务器发送请求消息,Web服务器再返回响应消息,这时收发数据的过程就全部结束了,服务器一方会发起断开过程。当然,可能也有一些程序是客户端发送完数据就结束了,不用等服务器响应,这时客户端会先发起断开过程。这一判断是应用程序作出的,协议栈在设计上允许任何一方先发起断开过程。

无论哪种情况,完成数据发送的一方会发起断开过程,这里我们以服务器一方发起断开过程为例来进行讲解。首先,服务器一方的应用程序会调用Socket库的close程序。然后,服务器的协议栈会生成包含断开信息的TCP头部,具体来说就是将控制位中的FIN比特设为1。接下来,协议栈会委托IP模块向客户端发送数据(图2.12①)。同时,服务器的套接字中也会记录下断开操作的相关信息。


接下来轮到客户端了。当收到服务器发来的FIN为1的TCP头部时,客户端的协议栈会将自己的套接字标记为进入断开操作状态。然后,为了告知服务器已收到FIN为1的包,客户端会向服务器返回一个ACK号(图2.12②)。这些操作完成后,协议栈就可以等待应用程序来取数据了。

过了一会儿,应用程序就会调用read来读取数据。这时,协议栈不会向应用程序传递数据,而是会告知应用程序(浏览器)来自服务器的数据已经全部收到了。根据规则,服务器返回请求之后,Web通信操作就全部结束了,因此只要收到服务器返回的所有数据,客户端的操作也就随之结束了。因此,客户端应用程序会调用close来结束数据收发操作,这时客户端的协议栈也会和服务器一样,生成一个FIN比特为1的TCP包,然后委托IP模块发送给服务器(图2.12③)。一段时间之后,服务器就会返回ACK号(图2.12④)。到这里,客户端和服务器的通信就全部结束了。

删除套接字

和服务器的通信结束之后,用来通信的套接字也就不会再使用了,这时我们就可以删除这个套接字了。不过,套接字并不会立即被删除,而是会等待一段时间之后再被删除。

等待这段时间是为了防止误操作,引发误操作的原因有很多,这里无法全部列举,下面来举一个最容易理解的例子。假设和图2.12的过程相反,客户端先发起断开,则断开的操作顺序如下。

则断开的操作顺序如下。

(1)客户端发送FIN
(2)服务器返回ACK号
(3)服务器发送FIN
(4)客户端返回ACK号

如果最后客户端返回的ACK号丢失了,结果会如何呢?这时,服务器没有接收到ACK号,可能会重发一次FIN。如果这时客户端的套接字已经删除了,会发生什么事呢?套接字被删除,那么套接字中保存的控制信息也就跟着消失了,套接字对应的端口号就会被释放出来。这时,如果别的应用程序要创建套接字,新套接字碰巧又被分配了同一个端口号[插图],而服务器重发的FIN正好到达,会怎么样呢?本来这个FIN是要发给刚刚删除的那个套接字的,但新套接字具有相同的端口号,于是这个FIN就会错误地跑到新套接字里面,新套接字就开始执行断开操作了。之所以不马上删除套接字,就是为了防止这样的误操作。

至于具体等待多长时间,这和包重传的操作方式有关。网络包丢失之后会进行重传,这个操作通常要持续几分钟。如果重传了几分钟之后依然无效,则停止重传。在这段时间内,网络中可能存在重传的包,也就有可能发生前面讲到的这种误操作,因此需要等待到重传完全结束。协议中对于这个等待时间没有明确的规定,一般来说会等待几分钟之后再删除套接字。

数据收发操作小结

到这里,用TCP协议收发应用程序数据的操作就全部结束了。这部分内容的讲解比较长,所以最后我们再整理一下。

数据收发操作的第一步是创建套接字。一般来说,服务器一方的应用程序在启动时就会创建好套接字并进入等待连接的状态。客户端则一般是在用户触发特定动作,需要访问服务器的时候创建套接字。在这个阶段,还没有开始传输网络包。

创建套接字之后,客户端会向服务器发起连接操作。首先,客户端会生成一个SYN为1的TCP包并发送给服务器(图2.13①)。这个TCP包的头部还包含了客户端向服务器发送数据时使用的初始序号,以及服务器向客户端发送数据时需要用到的窗口大小[插图]。当这个包到达服务器之后,服务器会返回一个SYN为1的TCP包(图2.13②)。和图2.13①一样,这个包的头部中也包含了序号和窗口大小,此外还包含表示确认已收到包①的ACK号[插图]。当这个包到达客户端时,客户端会向服务器返回一个包含表示确认的ACK号的TCP包(图2.13③)。到这里,连接操作就完成了,双方进入数据收发阶段。

数据收发阶段的操作根据应用程序的不同而有一些差异,以Web为例,首先客户端会向服务器发送请求消息。TCP会将请求消息切分成一定大小的块,并在每一块前面加上TCP头部,然后发送给服务器(图2.13④)。TCP头部中包含序号,它表示当前发送的是第几个字节的数据。当服务器收到数据时,会向客户端返回ACK号(图2.13⑤)。在最初的阶段,服务器只是不断接收数据,随着数据收发的进行,数据不断传递给应用程序,接收缓冲区就会被逐步释放。这时,服务器需要将新的窗口大小告知客户端。当服务器收到客户端的请求消息后,会向客户端返回响应消息,这个过程和刚才的过程正好相反(图2.13⑥⑦)。

服务器的响应消息发送完毕之后,数据收发操作就结束了,这时就会开始执行断开操作。以Web为例,服务器会先发起断开过程[插图]。在这个过程中,服务器先发送一个FIN为1的TCP包(图2.13⑧),然后客户端返回一个表示确认收到的ACK号(图2.13⑨)。接下来,双方还会交换一组方向相反的FIN为1的TCP包(图2.13⑩)和包含ACK号的TCP包(图2.13⑪)。最后,在等待一段时间后,套接字会被删除。

从服务器断开并删除套接字相关推荐

  1. 用友备份文件怎么与服务器断开,用友软件帐套的备份方法及帐套恢复方法规整...

    一. 备份方法:(三种:帐套备份.年账备份以及数据库备份) ①从系统管理里作备份,包括帐套的备份(以admin身份进入系统管理备份)和年度帐的备份(以帐套主管身份进入系统管理备份):这种备份的优点是简 ...

  2. c 套接字服务器端发送消息,从客户端C、服务器Python Issu发送套接字

    我当前的应用程序包括一个C客户机使用TCP将文件发送到Python服务器.它将生成文件的哈希值并将信息发回.我可以让它与python客户机一起工作,但是在将客户机迁移到C时遇到了问题.python服务 ...

  3. python编程示例_Python套接字编程–服务器,客户端示例

    python编程示例 Good Day Learners! In our previous tutorial, we discussed about Python unittest module. T ...

  4. 套接字的连接(服务器与客户端一对一的连接)

    套接字:是一种通信机制,通过这种机制,客户/服务器系统的开发工作既可以在本机可以络进行.                                   注:套接字的创建和使用与管道是有区别的,套 ...

  5. Java 套接字(Socket)

    网络应用模式主要有: 主机/终端模式:集中计算,集中管理: 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理: 浏览器/服务器模式:利用Internet跨平台. www ...

  6. linux编程本地套接字

    linux编程本地套接字 本地套接字是 IPC,也就是本地进程间通信的一种实现方式.除了本地套接字以外,其它技术,诸如管道.共享消息队列等也是进程间通信的常用方法,但因为本地套接字开发便捷,接受度高, ...

  7. TCP/IP网络编程---Linux系统下的TCP套接字编程

    目录 第一章 理解网络编程和套接字 1.1 网络编程和套接字概要 1.2 基于Linux的文件操作 1.2.1 底层文件访问和文件描述符 1.2.2 打开文件 1.2.3 关闭文件 1.2.4 将数据 ...

  8. 《Windows网络编程案例教程》-董相志 学习记录 阻塞/非阻塞套接字编程

    <Windows网络编程案例教程>-董相志 学习记录 阻塞/非阻塞套接字编程 2.3 阻塞/非阻塞套接字编程 阻塞套接字编程通信流程图 2.3.1 阻塞套接字客户机编程 1.启动并初始化W ...

  9. Java知多少(105)套接字(Socket)

    网络应用模式主要有: 主机/终端模式:集中计算,集中管理: 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理: 浏览器/服务器模式:利用Internet跨平台. www ...

最新文章

  1. 【每周CV论文】初学深度学习图像超分辨应该要读的文章
  2. JavaScript实现Fast Powering算法(附完整源码)
  3. Matplotlib(一)工作流程
  4. 深圳SQL数据库823报错修复
  5. AntDesignPro一次添加多条数据的表单字数限制,并且把input框变为可变文本框
  6. java分布式对象RMI应用测试用例
  7. mvn clean install 与 mvn install 的区别
  8. 移动端ajax,移动端ajax请求问题?
  9. 设计模式之组合模式(十四)
  10. Oracle 数据库导出(exp)导入(imp)说明
  11. Navicat Premium 12.1.21 最新版激活工具及方法
  12. 计算机基础知识教程excel试题,大学生计算机基础excel试题及答案
  13. docker 的初步接触
  14. 计算机作业word电子杂志,怎么用Word文档制作电子杂志目录
  15. HTML5视频自动循环播放
  16. n阶奇数魔方阵c语言编程,n阶魔方阵C语言
  17. CodeBlocks 20.3无法编译C++文件
  18. 牛逼!百度大佬深度分享AI助力RNA二级结构预测!
  19. 第十八天:WEB攻防-ASP安全MDB下载植入IIS短文件名写权限解析
  20. Verilog coding style

热门文章

  1. RDD的创建 -Scala educoder
  2. oracle dataguard详解,Oracle 19c 新特性详解:DataGuard 中ADG的自动DML重定向
  3. 云服务器如何清理垃圾释放空间?
  4. eclipse jdk配置_第一节:学会Java前提-手把手教你配置JDK环境变量
  5. windows bat与vbs与reg脚本整合 持续更新
  6. 人生的四大天规,越早明白,越有福气
  7. Python求1~300之间所有的完数
  8. excel的mysql语言_Excel的数据库语句
  9. phpmyadmin的config-default-php文件中各个配置参数的详细说明
  10. docker 删除包含关键字的镜像_Docker 架构及工作原理