网络协议--TCP的保活定时器

news2024/10/6 2:30:19

23.1 引言

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

这意味着两个应用进程—客户进程或服务器进程—都没有使用应用级的定时器来检测非活动状态,而这种非活动状态可以导致应用进程中的任何一个终止其活动。回想在第10.7节末尾曾提到过的BGP每隔30秒就向对端发送一个应用的探查,就是独立于TCP的保活定时器之外的应用定时器。

然而,许多时候一个服务器希望知道客户主机是否崩溃并关机或者崩溃又重新启动。许多实现提供的保活定时器可以提供这种能力。

保活并不是TCP规范中的一部分。Host Requirements RFC提供了3个不使用保活定时器的理由:(1)在出现短暂差错的情况下,这可能会使一个非常好的连接释放掉;(2)它们耗费不必要的带宽;(3)在按分组计费的情况下会在互联网上花掉更多的钱。然而,许多实现提供了保活定时器。

保活定时器是一个有争论的功能。许多人认为如果需要,这个功能不应该在TCP中提供,而应该由应用程序来完成。这是应当认真对待的一些问题之一,因为在这个论题上有些人表达出了很大的热情。

在连接两个端系统的网络出现临时故障的时候,保活选项会引起一个实际上很好的连接终止。例如,如果在一个中间路由器崩溃并重新启动时发送保活探查,那么TCP会认为客户的主机已经崩溃,而实际上所发生的并非如此。

保活功能主要是为服务器应用程序提供的。服务器应用程序希望知道客户主机是否崩溃,从而可以代表客户使用资源。许多版本的Rlogin和Telnet服务器默认使用这个选项。

一个说明现在需要使用保活功能的常见例子是当个人计算机用户使用TCP/IP向一个使用Telnet的主机注册时。如果在一天结束时,他们仅仅关闭了电源而没有注销,那么便会留下一个半开放的连接。在图18-16中,我们看到通过一个半开放连接发送数据会导致返回一个复位,但那是在来自正在发送数据的客户端。如果客户已经消失了,使得在服务器上留下一个半开放连接,而服务器又在等待来自客户的数据,则服务器将永远等待下去。保活功能就是试图在服务器端检测到这种半开放的连接。

23.2 描述

在这个描述中,我们称使用保活选项的一端为服务器,而另一端则为客户。并没有什么使客户不能使用这个选项,但通常都是服务器设置这个功能。如果双方都特别需要了解对方是否已经消失,则双方都可以使用这个选项(在29章我们将看到NFS使用TCP时,客户和服务器都设置了这个选项。但在第26章讲到Telnet和Rlogin时,只有服务器设置了这个选项,而客户则没有)。

如果一个给定的连接在两个小时之内没有任何动作,则服务器就向客户发送一个探查报文段(我们将在随后的例子中看到这个探查报文段看起来像什么)。客户主机必须处于以下4个状态之一。

  1. 客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常工作的。服务器在两小时以后将保活定时器复位。如果在两个小时定时器到时间之前有应用程序的通信量通过此连接,则定时器在交换数据后的未来2小时再复位。
  2. 客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务器将不能够收到对探查的响应,并在75秒后超时。服务器总共发送10个这样的探查,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
  3. 客户主机崩溃并已经重新启动。这时服务器将收到一个对其保活探查的响应,但是这个响应是一个复位,使得服务器终止这个连接。
  4. 客户主机正常运行,但是从服务器不可达。这与状态2相同,因为TCP不能够区分状态4与状态2之间的区别,它所能发现的就是没有收到探查的响应。

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

在第1种情况下,服务器的应用程序没有感觉到保活探查的发生。TCP层负责一切。这个过程对应用程序都是透明的,直至第2、3或4种情况发生。在这三种情况下,服务器应用程序将收到来自它的TCP的差错报告(通常服务器已经向网络发出了读操作请求,然后等待来自客户的数据。如果保活功能返回一个差错,则该差错将作为读操作的返回值返回给服务器)。在第2种情况下,差错是诸如“连接超时”之类的信息,而在第3种情况则为“连接被对方复位”。第4种情况看起来像是连接超时,也可根据是否收到与连接有关的ICMP差错来返回其他的差错。在下一节中我们将观察这4种情况。

一个被人们不断讨论的关于保活选项的问题就是两个小时的空闲时间是否可以改变。通常他们希望该数值可以小得多,处在分钟的数量级。正如我们在附录E看到的,这个值通常可以改变,但是在该附录所描述的所有系统中,保活间隔时间是系统级的变量,因此改变它会影响到所有使用该功能的用户。Host Requirements RFC提到一个实现可提供保活的功能,但是除非应用程序指明要这样,否则就不能使用该功能。而且,保活间隔必须是可配置的,但是其默认值必须不小于两个小时。

23.3 保活举例

现在详细讨论前一节提到的第2、3和4种情况。我们将在使用这个选项的情况下检查所交换的分组。

23.3.1 另一端崩溃

首先观察另一端崩溃且没有重新启动的情况下所发生的现象。为模拟这种情况,我们采用如下步骤:

  1. 在客户(主机bsdi上运行的sock程序)和主机svr4上的标准回显服务器之间建立一个连接。客户使用-K选项使能保活功能。
  2. 验证数据可以通过该连接。
  3. 观察客户TCP每隔2小时发送保活分组,并观察被服务器的TCP确认。
  4. 将以太网电缆从服务器上拔掉直到这个例子完成,这会使客户认为服务器主机已经崩溃。
  5. 我们预期服务器在断定连接已中断前发送10个间隔为75秒的保活探查。

这里是客户端的交互输出结果:
在这里插入图片描述

图23-1显示的是tcpdump的输出结果(已经去掉了连接建立和窗口通告)。
在这里插入图片描述

客户在第1、2和3行向服务器发送“Hello,world”并得到回显。第4行是第一个保活探查,发生在两个小时以后(7200秒)。在第6行的TCP报文段能够发送之前,首先观察到的是一个ARP请求和一个ARP应答。第6行的保活探查引出来自另一端的响应(第7行)。两个小时以后,在第7和8行发生了同样的分组交换过程。

如果能够观察到第6和第10行的保活探查中的所有字段,我们就会发现序号字段比下一个将要发送的序号字段小1(在本例中,当下一个为14时,它就是13)。但是因为报文段中没有数据,tcpdump不能打印出序号字段(它仅能够打印出设置了SYN、FIN或RST标志的空数据的序号)。正是接收到这个不正确的序号,才导致服务器的TCP对保活探查进行响应。这个响应告诉客户,服务器下一个期望的序号是14。

一些基于4.2BSD的旧的实现不能够对这些保活探查进行响应,除非报文段中包含数据。某些系统可以配置成发送一个字节的无用数据来引出响应。这个无用数据是无害的,因为它不是所期望的数据(这是接收方前一次接收并确认的数据),因此它会被接收方丢弃。其他一些系统在探查的前半部分发送4.3BSD格式的报文段(不包含数据),如果没有收到响应,在后半部分则切换为4.2BSD格式的报文段。

接着我们拔掉电缆,并期望两个小时的再一次探查失败。当这下一个探查发生时,注意到从来没有看到电缆上出现TCP报文段,这是因为主机没有响应ARP请求。在放弃之前,我们仍可以观察到客户每隔75秒发送一个探查,一共发送了10次。从交互式脚本可以看到返回给客户进程的差错码被TCP转换为“连接超时”,这正是实际所发生的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1148867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应用开发平台集成工作流系列之17——流程建模功能前端设计与改造回顾

背景 对于流程设置不友好的问题,国内钉钉另行设计与实现了一套流程建模模式,跟bpmn规范无关,有人仿照实现了下,并做了开源(https://github.com/StavinLi/Workflow-Vue3),效果图如下&#xff1a…

python设计模式笔记1:创建型模式 工厂模式和抽象工厂模式

1.工厂模式 (1) 导入所需的模块( json 和 ElementTree )。 (2) 定义 JSON数据提取器类( JSONDataExtractor )。 (3) 定义 XML数据提取器类( XMLDataExtractor )。 (4) 添加工厂函数 dataextraction_factor…

【错误解决方案】ModuleNotFoundError: No module named ‘PeptideBuilder‘

1. 错误提示 在python程序中,试图导入一个不存在的模块PeptideBuilder导致的错误: 错误提示:ModuleNotFoundError: No module named PeptideBuilder 2. 解决方案 解决方案是确保你已经正确安装了PeptideBuilder模块。你可以通过pip来安装它…

操作系统章节练习

第5章 存储器管理 一. 多选题(共8题,64分) 1. (多选题, 8分)为什么在页式存储器中实现程序共享时,必须对共享程序给出相同的页号? A. 共享页号相同方便地址转换。B. 实现程序共享时,由于页式存储结构要求…

多线程---线程池

文章目录 什么是线程池?线程池的实现标准库中的线程池(四种)自己实现一个线程池 线程池支持的参数在实际的开发中,线程池的线程数如何确定? 什么是线程池? 线程诞生的原因就是进程太“重量”了。虽然线程的…

计算机网络——第一章体系结构相关习题及详细解析

1-1 在OSI参考模型中,自下而上第一个提供端到端服务的层次是: A.数据链路层 B.传输层 C.会话层 D.应用层 答案选择:B.传输层 即,在OSI参考模型中,自下而上第一个提供端到端服务的层次是传输层。…

【数据结构】 队列详解!庖丁解牛般细致讲解!

🎥 屿小夏 : 个人主页 🔥个人专栏 : 数据结构解析 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言🌤️队列的概念剖析☁️什么是队列☁️队列的特性☁️队列的图解 &#x1…

【鸿蒙软件开发】ArkTS容器组件之Badge

文章目录 前言一、Badge组件1.1 子组件1.2 接口接口1参数 接口2参数 BadgePosition枚举说明BadgeStyle对象说明 1.3 示例代码 总结 前言 Badge组件:可以附加在单个组件上用于信息标记的容器组件。 一、Badge组件 可以附加在单个组件上用于信息标记的容器组件。 说…

光强的检测与控制系统设计

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、实习内容二、实习方法2.1 proteus仿真部分2.2 使用Altium designer软件绘制原理图2.2.1 工程创建2.2.2 绘制封装以及链接封装与原件原理图2.2.3检查原件原理…

python不同版本的下载安装和配置

python下载和安装 1 基础软件安装 sudo apt update sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget2 python压缩文件下载 我这里下载的是3.9.9,各位也可以根据自己需要下…

精品Python的定制化图书借阅推荐引擎设计与实现

《[含文档PPT源码等]精品基于Python的定制化图书推荐引擎设计与实现》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功! 软件开发环境及开发工具: 开发语言:python 使用框架:Django 前端技…

【机器学习】loss损失讨论

大纲 验证集loss上升,准确率也上升(即将overfitting?)训练集loss一定为要为0吗 Q1. 验证集loss上升,准确率也上升 随着置信度的增加,一小部分点的预测结果是错误的(log lik 给出了指数级的惩…

VSCode编写Unity代码自动补全配置

1.下载并安装.NET 7.0(C#插件需要)和.NET Framework 4.7.1(Unity需要) .NET 7.0下载链接:https://dotnet.microsoft.com/en-us/download .NET Framework 4.7.1下载链接:https://dotnet.microsoft.com/en-…

Python 日期和时间处理教程:datetime 模块的使用

Python 中的日期不是独立的数据类型,但我们可以导入一个名为 datetime 的模块来使用日期作为日期对象。 示例:导入 datetime 模块并显示当前日期: import datetimex datetime.datetime.now() print(x)日期输出 当我们执行上面示例中的代码…

Java利用Scanner类,从键盘接受一个字符串输入,该字符串包含小写字母,大写字母和数字。分别输出该字符串所包含的大写字母、小写字母和数字的个数。

题目要求:利用Scanner类,从键盘接受一个字符串输入,该字符串包含小写字母,大写字母和数字。分别输出该字符串所包含的大写字母、小写字母和数字的个数。 import java.util.Scanner;public class Demo1 {public static void main(…

算法篇 : 并查集

介绍 英文名:union find set 作用:合并集合,查询集合 合并:将有直接关系的顶点放在一个集合里面 查找:查询某个顶点所属的集合 集合的标志:用祖先点的标号作为每个集合的标识 案例 如果说将下图的集合2合并…

H5游戏源码分享-接苹果游戏拼手速

H5游戏源码分享-接苹果游戏拼手速 看看在20秒内能接多少个苹果 <html> <head><title>我是你的小苹果</title><meta charset"utf-8"/><meta name"viewport" content"initial-scale1, user-scalableno, minimum-scale…

【DevChat】智能编程助手 - 使用评测

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

【unity小技巧】unity排序问题的探究

文章目录 前言一、排序图层二、sorting Group的使用三、树木排序设计方法一 代码控制方法二 拆分图片方法三 透视排序1. 普通物品排序2. TileMap瓦片排序设计 完结 前言 unity的排序问题其实之前分享的项目多多少少都有提到一点&#xff0c;但是没有单独拿出来说&#xff0c;所…

常用第三方库

Moment GTC(Greenwish Mean Time)&#xff1a;格林威治时间&#xff0c;太阳时&#xff0c;精确到毫秒UTC(Universal Time Coodinated)&#xff1a;世界协调时间&#xff0c;原子种计时&#xff0c;精确到纳秒 GTC和UTC都是以0时区作为标准时间戳&#xff1a;以UTC的1970-1-1 …