TCP/IP卷一:80---TCP数据流与窗口管理之(延时确认(延迟ACK)、Nagle算法)

article/2025/7/23 4:06:55

一、延迟确认(延迟ACK)

  • 在许多情况下,TCP并不对每个到来的数据包都返回ACK,利用TCP的累积ACK字段(参见TCP报文格式https://blog.csdn.net/qq_41453285/article/details/104016416)就能实现该功能
  • 累积确认可以允许TCP延迟一段时间发送ACK,以便将ACK和相同方向上需要传的数据结合发送。这种捎带传输的方法经常用于批量数据传输
  •  显然,TCP不能任意时长地延迟ACK;否则对方会误认为数据丢失而出现不必要的重传

不同操作系统对延迟确认的实现

  • 采用延时ACK的方法会减少ACK传输数目,可以一定程度地减轻网络负载。对于批量数据传输通常为2:1的比例。基于不同的主机操作系统,延迟发送ACK的最大时延可以动态配置
  • Linux使用了一种动态调节算法,可以在每个报文段返回一个ACK (称为“快速 确认”模式)与传统延时ACK模式间相互切换
  • Mac OS X中,可以改变系统变量net.inet. tcp.delayed_ack值来设置延时ACK。可选值如下:禁用延时(设为0),始终延时(设为1),每隔一个包回复一个ACK(设为2),自动检测确认时间(设为3)。默认值为3
  • 最新的 Windows版本中,注册表项中,每个接口的全局唯一标识(GUID)都不同(IG表示被引用的特定网络接口的GUID)。TcpAckFrequency值(需要被添加)可以设为0-255,默认为2。它代表延时ACK计时器超时前在传的ACK数目。将其设为1表明对每个收到的报文段都生成相应的ACK。ACK计时器值可以通过TcpDelAckTicks注册表项控制。该值可设为2 - 6,默认为2。它以百毫秒为单位,表明在发送延时ACK前要等待百毫秒数

  • 之前提到过,通常TCP在某些情况下使用延时ACK的方法,但时延不会很长。在后面“TCP拥塞控制”文章中大量采用了延时ACK的方法,我们将会看到TCP怎样在处理批量数据的大数据包传输中实现拥塞控制
  • 小数据包传输中,如交互式应用,需要采用另外的算法。将该算法与延时ACK结合使用,如果处理不好,反而会导致性能降低。下面我们详细讨论该算法

二、Nagle算法

设计Nagle算法的初衷

  • 从前面的小节中可以知道,在ssh连接中,通常单次击键就会引发数据流的传输。如果使用IPv4,一次接键会生成约88字节大小的TCP/IPv4包(使用加密和认证):20字节的IP头部,20字节的TCP头部(假设没有选项),数据部分为48字节。这些小包(称为微型报)会造成相当高的网络传输代价。也就是说,与包的其他部分相比,有效的应用数据所占比例甚微
  • 该问题对于局域网不会有很大影响,因为大部分局域网不存在拥塞,而且这些包无须传输很远。然而对于广域网来说则会加重拥塞,严重影响网络性能
  • John Nagle在[RFCO896]中提出了一种简单有效的解决方法,现在称其为Nagle算法
  • 下面首先介绍该算法是怎样运行的,接着我们会讨论结合延时ACK方法使用时可能出现的一些缺陷和问题

Nagle算法实现原理

  • Nagle算法要求,当一个TCP连接中有在传数据时(即那些已发送但还未经确认的数据),小的报文段(长度小于SMSS)就不能被发送,直到所有的在传数据都收到ACK。并且,在收到ACK后,TCP需要收集这些小数据,将其整合到一个报文段中发送
  • 这种方法迫使TCP遵循“停等规程”——只有等接收到所有在传数据的ACK后才能继续发送
  • 该算法的精妙之处在于它实现了自时钟控制:ACK返回越快,数据传输也越快。在相对高延迟的广域网中,更需要减少微型报的数目,该算法使得单位时间内发送的报文段数目更少。也就是说,RTT控制着发包速率

演示案例

  • 从前前面一篇文章的演示案例中可以看到,单个字节的发送、确认以及回显的RTT较小(15ms以下)。为更快地生成数据,我们需要每秒钟输入60个字符以上。这意味着,当两台主机之间以很小的RTT传输数据时,例如在同一个局域网中,我们将很难看到该算法的显著效果
  • 为了显示Nagle算法的效果,我们比较分析某个TCP应用使用和禁用该算法的行为。 我们对一个ssh版本的客户端做了一定的修改。利用一个RTT相对较大(约190ms)的连接,就可以看出区别
  • 首先观察禁用Nagle算法(ssh默认)的情况,如下图所示:
  • 上图中显示的传输是在初始的认证完成以后、登录会话开始时记录的。这时输入date命令,我们看到共捕获到了19个包,整个传输过程持续了0.58s。共有5个ssh请求包,7个ssh应答包,以及7个TCP层的纯ACK包(不包含数据)

  • 下面我们将在使用Nagle算法的情况下重复探测这一过程(即在相似的网络环境下),如下图所示:
  • 可以看到下图中的包数目要少于上图(少了8个)。另外一个明显的差异是,请求和响应包随时间分布呈一定的规律性。回想一下Nagle算法的原理,它迫使TCP遵循停等行为模式,因此TCP发送端只有在接收到全部ACK后才能继续发送。观察每组请求/响应的传输时刻——0.0、0.19、0.38以及0.57,我们可以发现它们遵循一定的模式:每两个间隔为190ms,恰为连接的RTT。每发送一组请求和响应包需要等待一个RTT,这就加长了整个传 输过程(需要0.80s而非前面的0.58s)

  • Nagle算法做出了一种折中:传输的包数目更少而长度更大,但同时传输时延也更长。从下图中可以更清晰地看出差别
  • 下图显示了Nagle算法的停等行为。左侧显示双向传输,而右侧使用Nagle算法,使得在任一给定时刻,只有一个方向保持传输状态

延迟ACK与Nagle算法结合

  • 若将延时ACK与Nagle算法直接结合使用,得到的效果可能不尽如人意
  • 考虑如下情形,客户端使用延时ACK方法发送一个对服务器的请求,而服务器端的响应数据并不适合在同一个包中传输(见下图)
  • 从图中可以看到:
    • 客户端:在接收到来自服务器端的两个包以后,客户端并不立即发送ACK,而是处于等待状态,希望有数据一同捎带发送。通常情况下,TCP在接收到两个全长的数据包后就应返回一个ACK,但这里并非如此
    • 服务器端:由于使用了Nagle算法,直到收到ACK前都不能发送新数据,因为任一时刻只允许至多一个包在传
    • 因此延时ACK与Nagle算法的结合导致了某种程度的死锁(两端互相等待对方做出行动)。幸运的是,这种死锁并不是永久的,在延时ACK计时器超时后死锁会解除。客户端即使仍然没有要发送的数据也无需再等待,而可以只发送ACK给服务器。然而,在死锁期间整个传输连接处于空闲状态,使性能变差。在某些情况下,如这里的ssh传输,可以禁用Nagle算法

禁用Nagle算法

  • 从前面的例子可以看到,在有些情况下并不适用Nagle算法。典型的包括那些要求时延尽量小的应用,如远程控制中鼠标或接键操作需要及时送达以得到快捷的反馈。另一个例子是多人网络游戏,人物的动作需要及时地传送以确保不影响游戏进程(也不致影响其他玩家的动作)
  • 禁用Nagle算法有多种方式,主机需求RFC列出了相关方法:
    • 若某个应用使用Berkeley套接字API,可以设置TCP_NODELAY选项(见文章:https://blog.csdn.net/qq_41453285/article/details/89541693)
    • 另外,也可以在整个系统中禁用该算法。在Windows系统中,使用如下的注册表项:
      • 这个双字节类型的值必须由用户添加,应将其设为1。为使更改生效,消息队列也需要重新设置


http://chatgpt.dhexx.cn/article/4EFgGuF2.shtml

相关文章

禁用 Nagle 算法

有没有发现一个很奇怪的组合,即 Nagle 算法和延时 ACK 的组合。这个组合为什么奇怪呢? 我举一个例子你来体会一下。比如,客户端分两次将一个请求发送出去,由于请求的第一部分的报文未被确认,Nagle 算法开始起作用&…

TCP Nagle算法及示例

TCP nagle算法是说,一个TCP连接只允许有一个未被确认的小数据包,如果有小数据包未被确认,其他要发送的小数据包先被缓存起来,等收到确认后, 把这些数据包再一块发送出去。注意算法中说的是小数据包,也就是n…

TCP-IP详解:Nagle算法

参考书籍:TCP/IP详解,卷1:协议 Small Packet Problem 在使用一些协议通讯的时候,比如Telnet,会有一个字节字节的发送的情景,每次发送一个字节的有用数据,就会产生41个字节长的分组&#xff0c…

TCP-Nagle:代码版本重新解释Nagle算法

开年来的第一份工作,就是在最新的内核上打补丁。 可没想到Nagle算法也被我冲进了去年的垃圾桶里。 在网上找了一些资料,理论很快被消化,但看了看内核的实现,久久没能动弹。坐了一天,才摸索出来点什么,觉得…

Nagle算法原理与实现详解

文章目录 背景Nagle算法详解算法实现实现开启与关闭Nagle算法 Nagle算法与延迟ACK参考 背景 TCP的数据流大致可以被分成两类: 交互式数据流 TCP交互数据流指的是:TCP连接中传输的所有数据的总和,包括控制命令(用于管理网络中连接…

TCP详解 (三)Nagle算法和延迟确认

文章目录 延迟确认Nagle算法Nagle算法遇上延迟确认关闭Nagle算法 一些有关TCP通信量的研究如[Caceresetal.1991]发现,如果按照分组数量计算,约有一半的TCP报文段包含成块数据(如 FTP、电子邮件和 Usenet新闻),另一半则…

复指数信号正交性的简单证明

复指数信号为: . 写成矢量形式: 复指数信号两两正交,也就是两个复指数信号的内积有如下表示: 将上式内积形式展开: 当kl时,所有cos项1,sin项0,求和为N。 当时,将求和符…

三角函数正交性的推导

定理: 一个三角函数系:1 cosx sinx cos 一个三角函数系:1,cosx , sinx , cos2x , sin2x , … , cosnx , sinnx , … 如果这一堆函数(包括常数1)中任何两个不同函数的乘积在区间[-π, π]上的积分等于…

OFDM时频脉冲形状与子载波正交性的理解

从多载波调制的角度来理解子载波间正交,首先要明确OFDM默认的脉冲成型是时域矩形窗,时域上每个子载波 e j 2 π f n t e^{j2πf_nt} ej2πfn​t 都被一个矩形窗脉冲 g T ( t ) g_T(t) gT​(t)成型。其次,OFDM子载波间隔 等于 OFDM符号周期的…

正交性原理与维纳霍夫(正则)方程

有期望信号d(n),纯净信号x(n),以及噪声信号g(n); 有滤波器h(m),以及滤波器输出信号y(n),滤波器输出纯净信号x的估计值y&a…

三大变换与自控(五)三角函数的正交性证明

在本系列文章的第一篇中,我们提到任何信号都可以被分解为三角函数,是因为三角函数的正交性,因此在三角函数构建的坐标系中可以绘制任何图形。现在我们就来证明一下三角函数的正交性,以完善我们整个推导过程。 教材上的三角函数系…

机器学习的数学基础(3):正交性原理(orthogonality principle)

思考这样一个问题,令S为一个希尔伯特空间,而空间S的一个子空间 当我们给定了,如何求最近上距离x最近的点。 则我们用数学语言表示该问题为一个优化问题: 该问题的解可以直接通过一个定理给出,即正交性定理&#xff0…

傅里叶级数与傅里叶变换_Part1_三角函数系的正交性

傅里叶级数与傅里叶变换_Part1_三角函数系的正交性 参考链接: DR_CAN老师的原视频 0、复习Part0的内容 参考链接:傅里叶级数与傅里叶变换_Part0_欧拉公式证明三角函数和差公式证明 三角函数的和差公式如下 sin ⁡ ( α β ) sin ⁡ ( α ) cos ⁡ …

09 正交性

09 正交性 9-1 空间,向量空间和欧几里得空间 9-2 广义向量空间 9-3 子空间 9-4 维度 9-5 行空间和矩阵的行秩 9-6 列空间 9-7 矩阵的秩和矩阵的逆 9-8 零空间与看待零空间的三个视角 9-9 零空间与秩-零化度定理 9-10 左零空间,四大子空间和研究子空间的…

CSS正交性分析

Refer: 为什么 CSS 这么难学? 我先来解释一下什么是正交。你调过显示器的「亮度」、「色调」和「饱和度」吧。 「亮度」就是明暗程度,值越大,屏幕越亮。 「色调」就是颜色,你通过调色调,可以把红色调成绿色。 「饱和度…

勒让德多项式的正交性和归一化

罗德里格斯公式正交性归一化应用 这学期上数学课时老师布置了一道习题:计算勒让德多项式的模。翻看本科数学物理方法教材,发现计算方法较复杂,且用到了生成函数 为了方便理清整个计算过程,这一博客直接从罗德里格斯公式出发并避免…

向量组的正交性

向量的内积定义 运算: 向量的正交性: 正交向量组的性质: 向量组的正交规范化 正交矩阵 定义: 正交矩阵的判定

拉盖尔多项式的正交性

标准拉盖尔多项式 拉盖尔多项式可以表示为: 拉盖尔多项式的正交性是指 当 时 上式的积分运算结果为0。这是一种加权的正交性。 证明: (1) 采用变换 容易得到,当 上式的结果为0是因为在进行微分运算后,各项均包含 , 各项的上下限均为0。 …

三角函数系的正交性

参考资料: https://zhuanlan.zhihu.com/p/341796771https://www.bilibili.com/video/BV1Et411R78v