跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表

目录

  1. Chapter 22 TCP的坚持定时器
  2. 22.2 一个例子
  3. 22.3 糊涂窗口综合症
  4. Chapter 23 TCP的保活定时器
  5. 23.2 描述
  • 💰 8折买阿里云服务器限时8折了解详情
编程语言

TCP/IP协议详解卷一:TCP坚持定时器与保活定时器

TCP/IP协议详解卷一第22章和第23章分别介绍了TCP的坚持定时器与保活定时器机制。坚持定时器用于处理窗口大小为0时的ACK丢失问题,通过发送窗口探查报文段防止死锁,并涉及糊涂窗口综合症(SWS)的避免策略,包括接收方和发送方的窗口通告限制。保活定时器用于检测空闲连接中客户主机是否崩溃或不可达,服务器在长时间无数据交换后发送探查报文段,根据响应情况判断连接状态并终止无效连接,该功能对应用层透明但有助于资源管理。

WenxuanMa发布于 2020/8/3更新于 2026/4/212 浏览
TCP/IP协议详解卷一:TCP坚持定时器与保活定时器

Chapter 22 TCP的坚持定时器

TCP通过让接收方指明希望从发送方接收的数据字节数(即窗口大小)来进行流量控制。如果窗口大小为0,将有效地阻止发送方传送数据,直到窗口变为非0为止。TCP必须能够处理打开窗口的ACK丢失的情况。ACK的传输并不可靠。TCP不对ACK报文段进行确认,TCP只确认那些包含有数据的ACK报文段。

如果一个确认丢失了,则双方就有可能因为等待对方而使连接终止:接收方等待接收数据(因为它已经向发送方通告了一个非0的窗口),而发送方在等待允许它继续发送数据的窗口更新。为防止这种死锁情况的发生,发送方使用一个坚持定时器(persist timer)来周期性地向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查(window probe)。

22.2 一个例子

图22-1中,计算坚持定时器时使用了普通的TCP指数退避。对一个典型的局域网连接,首次超时时间算出来是1.5秒,第2次的超时值增加一倍,为3秒,再下次乘以4为6秒,之后再乘以8为12秒等。但是坚持定时器总是在5~60秒之间。

窗口探查包含一个字节的数据(图中序号为9217)。TCP总是允许在关闭连接前发送一个字节的数据。请注意,尽管如此,所返回的窗口为0的ACK并不是确认该字节(它们确认了包括9216在内的所有数据),因此这个字节被持续重传。

坚持状态与第21章中介绍的重传超时之间一个不同的特点就是TCP从不放弃发送窗口探查。这些探查每隔60秒发送一次,这个过程将持续到或者窗口被打开,或者应用进程使用的连接被终止。

22.3 糊涂窗口综合症

基于窗口的流量控制方案,如TCP所使用的,会导致一种被称为'糊涂窗口综合症(Silly Window Syndrome, SWS)'的状况。如果发生这种情况,则少量的数据将通过连接进行交换,而不是满长度的报文段。

该现象可发生在两端中的任何一端:接收方可以通告一个小的窗口(而不是一直等到有大的窗口时才通告),而发送方也可以发送少量的数据(而不是等待其他的数据以便发送一个大的报文段)。可以在任何一端采取措施避免出现糊涂窗口综合症的现象。

  1. 接收方不通告小窗口。通常的算法是接收方不通告一个比当前窗口大的窗口(可以为0),除非窗口可以增加一个报文段大小(也就是将要接收的MSS)或者可以增加接收方缓存空间的一半,不论实际有多少。
  2. 发送方避免出现糊涂窗口综合症的措施是只有以下条件之一满足时才发送数据:a. 可以发送一个满长度的报文段;b. 可以发送至少是接收方通告窗口大小一半的报文段;c. 可以发送任何数据并且不希望接收ACK(也就是说,没有还未被确认的数据)或者该连接上不能使用Nagle算法。

条件b主要对付那些总是通告小窗口(也许比1个报文段还小)的主机,条件c使我们在有尚未被确认的数据(正在等待被确认)以及在不能使用Nagle算法的情况下,避免发送小的报文段。如果应用进程在进行小数据的写操作(例如比该报文段还小),条件c可以避免出现糊涂窗口综合症。

这三个条件也可以让我们回答这样一个问题:在有尚未被确认数据的情况下,如果Nagle算法阻止我们发送小的报文段,那么多小才算是小呢?从条件a中可以看出所谓'小'就是指字节数小于报文段的大小。条件b仅用来对付较老的、原始的主机。

步骤2中的条件b要求发送方始终监视另一方通告的最大窗口大小,这是一种发送方猜测对方接收缓存大小的企图。虽然在连接建立时接收缓存的大小可能会减小,但在实际中这种情况很少见。

Chapter 23 TCP的保活定时器

可以没有任何数据流通过一个空闲的TCP连接。也就是说,如果TCP连接的双方都没有向对方发送数据,则在两个TCP模块之间不交换任何信息。例如,没有可以在其他网络协议中发现的轮询。这意味着我们可以启动一个客户与服务器建立一个连接,然后离去数小时、数天、数个星期或者数月,而连接依然保持。中间路由器可以崩溃和重启,电话线可以被挂断再连通,但是只要两端的主机没有被重启,则连接依然保持建立。

这意味着两个应用进程——客户进程或服务器进程—都没有使用应用级的定时器来检测非活动状态,而这种非活动状态可以导致应用进程中的任何一个终止其活动。然而,许多时候一个服务器希望知道客户主机是否崩溃并关机或者崩溃又重新启动。许多实现提供的保活定时器可以提供这种能力。保活并不是TCP规范中的一部分。保活功能主要是为服务器应用程序提供的。服务器应用程序希望知道客户主机是否崩溃,从而可以代表客户使用资源。许多版本的Rlogin和Telnet服务器默认使用这个选项。

23.2 描述

我们称使用保活选项的一端为服务器,而另一端则为客户。如果一个给定的连接在两个小时之内没有任何动作,则服务器就向客户发送一个探查报文段。客户主机必须处于以下4个状态之一:

  1. 客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常工作的。服务器在两小时以后将保活定时器复位。如果在两个小时定时器到时间之前有应用程序的通信量通过此连接,则定时器在交换数据后的未来2小时再复位。
  2. 客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都。服务器将不能够收到对探查的响应,并在75秒后超时。服务器总共发送个这样的探查,每个间隔。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • Java 并发编程:ForkJoin 分而治之框架
  • Dell R 系列服务器硬件整合后开机报错解决方案
  • DWR3 基于 Spring MVC 配置 Controller 的方法
  • Java Swing 网格布局 GridLayout 基础用法
  • Java util 包学习笔记一
  • K 均值聚类算法原理与步骤
  • MyBatis 动态 SQL 标签详解
  • Java 的 main 方法为什么必须是 public static void
  • Java JPA 核心概念与实现框架介绍

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online

没有响应
10
75秒
  • 客户主机崩溃并已经重新启动。这时服务器将收到一个对其保活探查的响应,但是这个响应是一个复位,使得服务器终止这个连接。
  • 客户主机正常运行,但是从服务器不可达。这与状态2相同,因为TCP不能够区分状态4与状态2之间的区别,它所能发现的就是没有收到探查的响应。
  • 第1种情况下,服务器的应用程序没有感觉到保活探查的发生。TCP层负责一切。这个过程对应用程序都是透明的,直至第2、3或4种情况发生。在这三种情况下,服务器应用程序将收到来自它的TCP的差错报告。在第2种情况下,差错是诸如'连接超时'之类的信息,而在第3种情况则为'连接被对方复位'。第4种情况看起来像是连接超时,也可根据是否收到与连接有关的ICMP差错来返回其他的差错。

    服务器不用关注客户主机被关闭和重新启动的情况(这指的是一个操作员的关闭,而不是主机崩溃)。当系统被操作员关闭时,所有的应用进程也被终止(也就是客户进程),这会使客户的TCP在连接上发出一个FIN。接收到FIN将使服务器的TCP向服务器进程报告文件结束,使服务器可以检测到这个情况。

    Python 基础语法:数字、表达式与字符串
  • VMware 克隆虚拟机后无法上网的解决方案
  • 消息队列核心面试题:应用场景与可靠性保障
  • Go 语言工程师如何进阶为云原生高级开发工程师
  • Redis 与 Memcached 核心区别及性能分析
  • 目前支持 HTML5 的浏览器有哪些?
  • JavaScript 判断字符串是否包含指定子串的方法
  • MySQL 索引底层数据结构及原理深入分析
  • 深入理解 volatile 关键字
  • 比萨中文离线地图应用上线
  • Spring HttpMediaTypeNotAcceptableException 异常分析与解决方案