免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2011 | 回复: 5
打印 上一主题 下一主题

[网络] 关于TCP/IP详解 卷1中 图19-4 Nagle算法的一个疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-28 22:59 |只看该作者 |倒序浏览
Nagle算法是讲 一个新的小报文要发送,必须等前一个小报文的ack收到之后才能发送;
在卷1的P204页图19-4讲解Nagle算法时,举的例子
  

图中报文14的ack还没有收到,报文15就发送出去了,感觉是违背了Nagle算法,书中还专门这对这个做了解释说没有违背Nagle算法:
报文段 14和15看起来似乎是与 Nagle算法相违背的,但我们需要通过检查序号来观察其中 的真相。因为确认序号是 54,因此报文段 14是报文段 12中确认的应答。但客户在发送该报文 段之前,接收到了来自服务器的报文段 13,报文段 15中包含了对序号为 56的报文段 13的确认。 因此即使我们看到从客户到服务器有两个连续返回的报文段,客户也是遵守了 Nagle算法的。

但是看了这个解释,还是迷迷糊糊的,有看懂了得帮忙指点一下,多谢

论坛徽章:
0
2 [报告]
发表于 2013-09-05 01:21 |只看该作者
回复 1# Huntsmen

我觉得解释的比较明白了吧.

14是对12的确认,12延迟大的原因可能是服务器比较忙,产生了delayed ack,所以只是一个ack报文,单很快又响应了一个数据报文13,可以看到client收到13和12的间隔只有0.0002秒。虽然在14发送之前收到了13,这个时候14已经组装好了(14是在收到12之后就准备组装发送的,恰好发送之前收到了13),所以先发送14,然后通过15再对刚收到的13进行确认,同时发送后续字节。在这里必须有一个对12进行确认的过程,即使你在收到13之后取消了14的发送,最终还是要发送新的14进行确认,与其这样何不按照上述直接发送呢,所以以上的处理是合理的。

因此14,15是和上一个会话关联的,不能只看14,15的关系,对14,15的确认(再加上17)在下面的16,18中体现。你可以再往后看看,16,18没有完全确认收到的字节数为3(14,15,17一共发送了3+1+3共7个字节,16,18只确认了3+1共4个字节,还有3个未确认),对于未确认的字节,最终体现在18响应的window size大小中,可以看到这个时候的window为8189,比最大值8192小3个字节,这就是上面那3个未确认的字节。

其实不是client不按标准的标准的Nagle进行一问一答,而是server由于本身的原因没有正常应答,client这种处理保证了最高的传输效率,试想你不对12确认,那么server是不是要再重传一次呢?或者你在14之后不发15,那么server的13是不是需要重传一次呢?所以针对12,13这中模式,必然存在14,15这种应答机制。

论坛徽章:
0
3 [报告]
发表于 2013-09-05 01:31 |只看该作者
本帖最后由 thinkdancer 于 2013-09-05 01:32 编辑

另外再补充一下,Nagle算法并不只单单是要求必须等收到ack之后再发送下一个,它的最终目的是收集小报文、用最少的发送次数、最大限度的发送报文,减少小报文的发送次数,提高在慢速网络中的发送效率。如果能够这样看待这个问题,则上述实现就比较容易理解了。
它的主要不足是:对于交互性强的应用来说,如果服务器启用了delayed ack, 则可能会影响交互体验,所以在这些应用中可能需要关闭Nagle算法,比如telnet客户端。

thinkdancer 发表于 2013-09-05 01:21
回复 1# Huntsmen

我觉得解释的比较明白了吧.

论坛徽章:
4
申猴
日期:2013-08-23 12:42:13双鱼座
日期:2013-09-30 08:41:52摩羯座
日期:2013-10-29 07:47:43处女座
日期:2013-12-01 11:31:30
4 [报告]
发表于 2013-09-05 14:06 |只看该作者
本帖最后由 huangya90 于 2013-09-05 14:15 编辑

回复 3# thinkdancer


    觉得你的说法有问题,欢迎探讨。
1.
14是对12的确认,
14不是对12的确认。client的tcp只是在收到报文12的时候,发送了报文14作为应答(nagle算法),原版的说法是
Segment 14 is in response to the ACK received in segment 12
12是一个确认报文,对于确认报文是不再发送一个确认报文的(也就是没有确认的确认)
2.
16,18没有完全确认收到的字节数为3(14,15,17一共发送了3+1+3共7个字节,16,18只确认了3+1共4个字节,还有3个未确认),对于未确认的字节,最终体现在18响应的window size大小中,可以看到这个时候的window为8189,比最大值8192小3个字节,这就是上面那3个未确认的字节。
报文16确认了报文14和报文15发送的字节,也就是4个字节,因为报文16的ack=18。报文18确认了报文17发送的3个字节。注意,发送确认是tcp的事,回显才是server的事。TCP可以在应用进程(在这里应用进程是server)读取并处理数据前发送所接收数据的确认。T C P确认仅仅表明T C P已经正确接收了数据。最后一个报文段的窗口大小为8 1 8 9而非8 1 9 2,表明服务器进程尚未读取这三个收到的数据,所以不能发送回显数据。
你的其它解释我同意。

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
5 [报告]
发表于 2013-12-31 13:34 |只看该作者
回复 2# thinkdancer


    》所以先发送14,然后通过15再对刚收到的13进行确认,
这里可以对13进行确认,但为什么一定还要携带一个数据?之前的14包不是已经发送了新的数据了吗,针对这个发出的新数据,还没有收到服务端返回的ACK,在这种情况下又通过15发送数据,这不是和NAGLE说法不一致吗?要知道现在TCP CONNECTION上有两个未确认的包

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
6 [报告]
发表于 2013-12-31 13:54 |只看该作者
本帖最后由 seufy88 于 2013-12-31 13:55 编辑

补充:
到底何时可以发送数据
到底何时才能发送数据呢?如果单从Nagle算法上看,很简单,然而事实证明,情况还要更复杂些。如果发送端已经排列了3个TCP分段,分段1,分段2,分段3依次被排入,三个分段都是小分段(不符合Nagle算法中立即发送的标准),此时已经有一个分段被发出了,且其确认还没有到来,请问此时能发送分段1和2吗?如果按照Nagle算法,是不能发送的,但实际上它们是可以发送的,因为这两个分段已经没有任何机会再积累新的数据了,新的数据肯定都积累在分段3上了。问题在于,分段还没有积累到一定大小时,怎么还可以产生新的分段?这是可能的,但这是另一个问题,在此不谈。
     Linux的TCP实现在这个问题上表现的更加灵活,它是这么判断能否发送的(在开启了Nagle的情况下):
IF (没有超过拥塞窗口大小的数据分段未确认 || 数据分段中包含FIN ) &&
    数据分段没有超越窗口边界
    Then
    IF 分段在中间(上述例子中的分段1和2) ||
           分段是紧急模式            ||
       通过Nagle算法
        Then 发送分段
    EndIF
EndIF
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP