前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >速读原著-TCP/IP(Nagle算法)

速读原著-TCP/IP(Nagle算法)

作者头像
cwl_java
发布2020-03-11 16:22:35
1.1K0
发布2020-03-11 16:22:35
举报
文章被收录于专栏:cwl_Javacwl_Java

第19章 TCP的交互数据流

19.4 Nagle算法

在前一节我们看到 , 在一个R l o g i n连接上客户一般每次发送一个字节到服务器,这就产生了一些4 1字节长的分组:2 0字节的I P首部、2 0字节的T C P首部和1个字节的数据。在局域网上,这些小分组(被称为微小分组( t i n y g r a m))通常不会引起麻烦,因为局域网一般不会出现拥塞。但在广域网上,这些小分组则会增加拥塞出现的可能。一种简单和好的方法就是采用RFC 896 [Nagle 1984]中所建议的N a g l e算法。

该算法要求一个 T C P连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组。相反, T C P收集这些少量的分组,并在确认到来时以一个分组的方式发出去。该算法的优越之处在于它是自适应的:确认到达得越快,数据也就发送得越快。而在希望减少微小分组数目的低速广域网上,则会发送更少的分组(我们将在2 2 . 3节看到“小”的含义是小于报文段的大小)。

在图1 9 - 3中可以看到,在以太网上一个字节被发送、确认和回显的平均往返时间约为 1 6m s。为了产生比这个速度更快的数据,我们每秒键入的字符必须多于 6 0个。这表明在局域网环境下两个主机之间发送数据时很少使用这个算法。

但是,当往返时间( RT T)增加时,如通过一个广域网,情况就会发生变化。看一下在主机s l i p和主机v a n g o g h . c s . b e r k e l e y . e d u之间的R l o g i n连接工作的情况。为了从我们的网络中出去(参看原书封面内侧),需要使用两个 S L I P链路和I n t e r n e t。我们希望获得更长的往返时间。图 1 9 - 4显示了当在客户端快速键入字符(像一个快速打字员一样)时一些数据流的时间系列(去掉了服务类型信息,但保留了窗口通告)。

比较图1 9 - 4与图1 9 - 3,我们首先注意到从s l i p到v a n g o g h不存在经受时延的A C K。这是因为在时延定时器溢出之前总是有数据等待发送。

其次,注意到从左到右待发数据的长度是不同的,分别为: 1、1、2、1、2、2、3、1和3个字节。这是因为客户只有收到前一个数据的确认后才发送已经收集的数据。通过使用 N a g l e算法,为发送1 6个字节的数据客户只需要使用 9个报文段,而不再是1 6个。

报文段1 4和1 5看起来似乎是与N a g l e算法相违背的,但我们需要通过检查序号来观察其中的真相。因为确认序号是 5 4,因此报文段1 4是报文段1 2中确认的应答。但客户在发送该报文段之前,接收到了来自服务器的报文段 1 3,报文段1 5中包含了对序号为5 6的报文段1 3的确认。

因此即使我们看到从客户到服务器有两个连续返回的报文段,客户也是遵守了 N a g l e算法的。在图1 9 - 4中可以看到存在一个经受时延的 A C K,但该A C K是从服务器到客户的(报文段1 2),因为它不包含任何数据,因此我们可以假定这是经受时延的 A C K。服务器当时一定非常忙,因此无法在服务器的定时器溢出前及时处理所收到的字符。

最后看一下最后两个报文段中数据的数量以及相应的序号。客户发送 3个字节的数据(1 8 ,1 9和2 0),然后服务器确认这 3个字节(最后的报文段中的 ACK 21),但是只返回了一个字节(标号为5 9)。这是因为当服务器的T C P一旦正确收到这3个字节的数据,就会返回对该数据的确认,但只有当R l o g i n服务器发送回显数据时,它才能够发送这些数据的回显。这表明 T C P可以 在应用读取并处理数据前发送所接收数据的确认。T C P确认仅仅表明T C P已经正确接收了数据。最后一个报文段的窗口大小为8 1 8 9而非8 1 9 2,表明服务器进程尚未读取这三个收到的数据。

在这里插入图片描述
在这里插入图片描述

19.4.1 关闭Nagle算法

有时我们也需要关闭 N a g l e算法。一个典型的例子是 X窗口系统服务器(见 3 0 . 5节):小消息(鼠标移动)必须无时延地发送,以便为进行某种操作的交互用户提供实时的反馈。

这里将举另外一个更容易说明的例子—在一个交互注册过程中键入终端的一个特殊功能键。这个功能键通常可以产生多个字符序列,经常从 A S C I I码的转义( e s c a p e )字符开始。如果T C P每次得到一个字符,它很可能会发送序列中的第一个字符( A S C I I码的E S C),然后缓存其他字符并等待对该字符的确认。但当服务器接收到该字符后,它并不发送确认,而是继续等待接收序列中的其他字符。这就会经常触发服务器的经受时延的确认算法,表示剩下的字符没有在200 ms内发送。对交互用户而言,这将产生明显的时延。

插口API用户可以使用T C P _ N O D E L A Y选项来关闭Nagle算法。Host Requirements RFC声明T C P必须实现N a g l e算法,但必须为应用提供一种方法来关闭该算法在某个连接上执行。

19.4.2 一个例子

可以在N a g l e算法和产生多个字符的按键之间看到这种交互的情况。在主机 s l i p和主机v a n g o g h . c s . b e r k e l e y . e d u之间建立一个R l o g i n连接,然后按下F 1功能键,这将产生3个字节:一个e s c a p e、一个左括号和一个 M。然后再按下F 2功能键,这将产生另外 3个字节。图1 9 - 5表示的是t c p d u m p的输出结果(我们去掉了其中的服务类型和窗口通告)。

在这里插入图片描述
在这里插入图片描述

图1 9 - 6表示了这个交互过程的时间系列。在该图的下面部分我们给出了从客户发送到服务器的6个字节和它们的序号以及将要返回的 8个字节的回显。

在这里插入图片描述
在这里插入图片描述

当r l o g i n客户读取到输入的第1个字节并向T C P写入时,该字节作为报文段 1被发送。这是F 1键所产生的3个字节中的第1个。它的回显在报文段 2中被返回,此时剩余的 2个字节才被发送(报文段3)。这两个字节的回显在报文段 4被接收,而报文段5则是对它们的确认。

第1个字节的回显为2个字节(报文段2)的原因是因为在A S C I I码中转义符的回显是2个字节:插入记号和一个左括号。剩下的两个输入字节:一个左括号和一个 M,分别以自身作为回显内容。

当按下下一个特殊功能键(报文段 6 ~ 1 0)时,也会发生同样的过程。正如我们希望的那样,在报文段 5和1 0(s l i p发送回显的确认)之间的时间差是 200 ms的整数倍,因为这两个A C K被进行时延。

现在我们使用一个修改后关闭了 N a g l e算法的r l o g i n版本重复同样的实验。图 1 9 - 7显示了t c p d u m p的输出结果(同样去掉了其中的服务类型和窗口通告)。

在这里插入图片描述
在这里插入图片描述

在已知某些报文段在网络上形成交叉的情况下,以该结果构造时间系列则更具有启发性和指导意义。这个例子同样也需要随着数据流对序号进行仔细的检查。在图 1 9 - 8中显示这个结果。用图1 9 - 7中t c p d u m p输出的号码对报文段进行了相应的编号。

我们注意到的第 1个变化是当3个字节准备好时它们全部被发送(报文段 1、2和3)。没有时延发生—N a g l e算法被禁止。

在t c p d u m p输出中的下一个分组(报文段 4)中带有来自服务器的第 5个字节及一个确认序号为4的A C K。这是不正确的,因为客户并不希望接收到第 5个字节,因此它立即发送一个确认序号为2而不是6的响应(没有被延迟)。看起来一个报文段丢失了,在图 1 9 - 8中我们用虚线表示。

如何知道这个丢失的报文段中包含第 2、3和4个字节,且其确认序号为 3呢?这是因为正如在报文段 5中声明的那样,我们希望的下一个字节是第 2个字节(每当 T C P接收到一个超出期望序号的失序数据时,它总是发送一个确认序号为其期望序号的确认)。也正是因为丢失的分组中包含第 2、3和4个字节,表明服务器必定已经接收到报文段 2,因此丢失的报文段中的确认序号一定为3(服务器期望接收的下一个字节号)。最后,注意到重传的报文段 6中包含有丢失的报文段中的数据和报文段 4,这被称为重新分组化。我们将在 2 2 . 11节对其进行更多的介绍。

现在回到禁止 N a g l e算法的讨论中来。可以观察到键入的下一个特殊功能键所产生的 3个字节分别作为单独的报文段(报文段 8、9和1 0)被发送。这一次服务器首先回显了报文段 8中的字节(报文段11),然后回显了报文段9和1 0中的字节(报文段1 2)。

在这个例子中,我们能够观察到的是在跨广域网运行一个交互应用的环境下,当进行多字节的按键输入时,默认使用 N a g l e算法会引起额外的时延。

在第2 1章我们将进行有关时延和重传方面的讨论。

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第19章 TCP的交互数据流
    • 19.4 Nagle算法
      • 19.4.1 关闭Nagle算法
      • 19.4.2 一个例子
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档