TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。

一个连TCP接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。

Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。(尤其在广域网中)(减少大量小包的发送)

Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。所谓“小段”,指的是小于MSS尺寸的数据块

所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

Nagle算法的规则(可参考tcp_output.c文件里tcp_nagle_check函数注释):

(1)如果包长度达到MSS,则允许发送;

(2)如果该包含有FIN,则允许发送;

(3)设置了TCP_NODELAY选项,则允许发送;(即关闭了Nagle算法了,可以立刻发)

(4)未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;

(5)上述条件都未满足,但发生了超时(一般为200ms),则立即发送。

Nagle算法只允许一个未被ACK的包存在于网络,它并不管包的大小,因此它事实上就是一个扩展的停-等协议(停止等待ARQ协议),只不过它是基于包停-等的,而不是基于字节停-等的。Nagle算法完全由TCP协议的ACK机制决定,这会带来一些问题,比如如果对端ACK回复很快的话,Nagle事实上不会拼接太多的数据包,虽然避免了网络拥塞,网络总体的利用率依然很低。  (好好理解这句话  就是如果ack回复的快   Nagle算法并不会来得急拼多大的包   虽然避免了网络拥塞,网络总体的利用率依然很低

TCP_NODELAY 套接字选项

默认情况下,发送数据采用Negle 算法。这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,

使用TCP_NODELAY选项可以禁止Negale 算法。 

延迟确认机制(TCP delayed acknowledgment)

全名Delayed Acknowledgment,简称延迟ACK,翻译为延迟确认。 

与Nagle算法一样,延迟ACK的目的也是为了减少网络中传输大量的小报文数,但该报文数是针对ACK报文的。

一个来自发送端的报文到达接收端,TCP会延迟ACK的发送,希望应用程序会对刚刚收到的数据进行应答,   这样就可以用新数据将ACK捎带过去。  (就是对请求应答的时候稍带上ack,不单独进行确认 就是这个意思咯) 

下面是讨论的重点!!!!!!

当Nagle算法遇到Delayed ACK

在一个有数据传输的TCP连接中,如果只有数据发送方启用Nagle算法,在其连续发送多个小报文时,Nagle算法机制会减少网络中的小报文数量。这就意味着,同样传输相同大小的应用数据,在网络上的报文个数却不同。 

举个例子,发送端需要连续发送5个写操作(应用程序将数据写入到缓冲池的动作)的小报文,首先发送第一个,由于Nagle算法的作用,在未收到第一个报文确认前发送端在等待写操作的同时进行读操作,接收端并未启用延迟确认(视TCP delay ACK时间为0),尽管刚收到该报文就发出确认,但由于网络延时的原因,在收集齐另外4个小报文后,发送方才收到了第一个报文的ACK,则后面的4个报文会一起发送出去(大小未超过MSS),接收端再次ACK。

在上述发送5个小报文的过程中,只用了4个报文就实现了。

如果发送端未启用Nagle算法,完成整个过程则至少需要8个报文或10个报文才能实现,这里接收端未启用延迟确认,如下图所示。启用Nagle算法和未启用Nagle算法的场景中,从完成数据发送的时间来看,未启用Nagle算法的方式花费的时间会更长一些,(也不一定吧个人觉得 还是要看网络环境  理论上是这样)  如下图所示。这里基本看到了Nagle算法的好处了。

还是上述数据传输场景,发送端未启用Nagle算法,但接收端延迟确认默认时间为200ms,来看看这时的情况。 RFC 1122规定,Delayed ACK对单个的小报文可以延长确认的时间,但不允许有两个连续的小报文不被确认。所以,当发送端连续发送两个报文后,接收端必须给予确认。这时的数据传输情况如下图,只有当第5个报文到达后,接收端由于延迟确认机制,会导致200ms的延时存在。

接下来看看,当Nagle算法遇到Delayed ACK时会是什么情况。按照常理推断,两种深思熟虑的功能设计,应该是1+1>2的效果。具体如何,还是请事实说话。

先继续看上面的假设场景,该场景要求发送端向接收端发送5个连续的写操作数据,但网络延时较大,同时发送端启用Nagle算法,接收端Delayed ACK默认为200ms。 

发送方先发出一个小报文,接收端收到后,由于延迟确认的机制,等待发送方的下一个报文到达。而发送方由于Nagle算法机制,在未接收到第一个报文的确认前,不会发送已读取到的报文。  在这种场景下,暂不考虑应用处理时间,完成整个数据传输所需时间为2RTT+400ms,貌似情况不是特别糟糕。

如果上述其他条件不变,发送方应用写操作延时稍微变大,或发送端的应用操作延时稍大,我们再看看,完成这个操作的延时情况。 

发送方先发出一个小报文,接收端收到后,由于延迟确认的机制,等待发送方的下一个报文到达。由于发送方应用数据写操作延时较大,在经过RTT+200ms后,读取到了下一个需要发送的内容,此时接收到了第一个报文的确认,而网络中未有没被确认的报文,发送方需要再将第二个小报文发送出去,以此类推,直到最后一个小报文被发送,且接收到该报文的确认,此时整个数据传输过程完成。

在这种情景下,完成整个数据传输所需时间则为5RTT+5*200ms,明显增大了不少。如果相同情境下,有成千上万的小报文发送,则整体使用时间相当可观了。

在实际情况下,如果发送方程序做了一系列的写、写、读操作的现象,这样的操作都会触发Nagle和延迟ACK算法之间的交互作用,应该尽量避免

 

TCP Nagle算法以及延迟确认(即延迟回复ACK)的学习的更多相关文章

  1. TCP Nagle算法&&延迟确认机制

    TCP Nagle算法&&延迟确认机制 收藏 秋风醉了 发表于 3年前 阅读 1367 收藏 0 点赞 0 评论 0 [腾讯云]买域名送云解析+SSL证书+建站!>>> ...

  2. linux tcp Nagle算法,TCP_NODELAY和TCP_CORK 转载

    转载自: http://www.cnhalo.net/2016/08/13/linux-tcp-nagle-cork/ http://abcdxyzk.github.io/blog/2018/07/0 ...

  3. TCP的ACK确认系列 — 延迟确认

    主要内容:TCP的延迟确认.延迟确认定时器的实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 延迟确认模式 发送方在发送数据包时,如果发送的数据包有 ...

  4. Nagle算法&&延时确认

    数据流分类 成块数据 交互数据   Rlogin需要远程系统(服务器)回显我们(客户)键入的字符 数据字节和数据字节的回显都需要对方确认 rlogin 每次只发送一个字节到服务器,而Telnet 可以 ...

  5. TCP/IP之Nagle算法与40ms延迟

    Nagle算法是针对网络上存在的微小分组可能会在广域网上造成拥塞而设计的.该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组确认到达之前不能发送其他的小分组.同时,TCP收集这 ...

  6. 延迟确认和Nagle算法

    前篇文章介绍了三次握手和四次挥手,了解了TCP是如何建立和断开连接的,文末还提到了抓包挥手时的一个“异常”现象,当时无法解释,特地查了资料,知道了数据传输中的延迟确认策略. 何谓延迟确认策略? WIK ...

  7. TCP之Nagle算法与延迟ACK

    (一)Nagle算法 为了减少网络中小分组的数目,减少网络拥塞的情况.Nagle算法要求在一条TCP连接上最多只能有一个未被确认的未完成小分组,在该分组ACK到达之前不能够发送其他的小分组,发送端需要 ...

  8. TCP之Nagle算法&&延迟ACK

    1. Nagle算法: 是为了减少广域网的小分组数目,从而减小网络拥塞的出现: 该算法要求一个tcp连接上最多只能有一个未被确认的未完成的小分组,在该分组ack到达之前不能发送其他的小分组,tcp需要 ...

  9. Linux下TCP延迟确认(Delayed Ack)机制导致的时延问题分析

    版权声明:本文由潘安群原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/105 来源:腾云阁 https://www.qclo ...

随机推荐

  1. c# 的默认访问修饰符小结(转)

    c# 的访问修饰符是private 还是 internal? 准确的说,不能一概而论. [MSDN] Classes and structs that are not nested within ot ...

  2. VS报错之混合模式程序集是针对“v1.1.4322”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。

    看到一个kinect大牛编写的一个水果忍者的体感游戏版本,让我为自己一直以来只用现有的网页游戏来模拟kinect体感游戏控制感到惭愧,没办法,我还是菜鸟.学习一段后自己模仿星际大战这个游戏,自己写了一 ...

  3. 自定义MVC的Helper扩展方法 转 Insus.NET

    记得在开发ASP.NET时候,也经常性使用C#可以写自己义的扩展方法,如: http://www.cnblogs.com/insus/p/3154363.html 或http://www.cnblog ...

  4. python 根据字典中的key,value进行排序

    #coding=utf-8 import requests,json,collections,base64,datetime def sort(datas): data=json.dumps(data ...

  5. linux源码安装apache

    apache安装之前,需要安装APR.APR-Util和PCRE依赖包 下载 Apache     下载地址: http://httpd.apache.org/download.cgi   (打开找最 ...

  6. EIP-uni-app框架-建立项目

    uni-app介绍 uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.H5.小程序等多个平台.uni-app在跨端数量,扩展能力, ...

  7. 使用metasploit进行栈溢出攻击-2

    基本的栈溢出搞明白了,真实攻击中一个很重要的问题是shellcode生成. 利用Metasploit提供的工具,可以方便的生成shellcode,然后可以使用第一篇中的代码进行验证. 先说一下如何生成 ...

  8. 封闭解(Closed-form solution)、解析解(Analytical solution)、数值解(Numerical solution) 释义

    转俞夕的博客 (侵删) 1 解析解 解析解(Analytical solution) 就是根据严格的公式推导,给出任意的自变量就可以求出其因变量,也就是问题的解,然后可以利用这些公式计算相应的问题.所 ...

  9. 使用Shader Graph实现《塞尔达传说:旷野之息》风格的着色器

    https://mp.weixin.qq.com/s/19Xq6wYuXP0gQJDvC9Fh0g

  10. P1505 [国家集训队]旅游

    \(\color{#0066ff}{题 目 描 述}\) Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了 ...