Networking Nagle算法和延迟确认是否用于批量数据?

Networking Nagle算法和延迟确认是否用于批量数据?,networking,tcp,Networking,Tcp,所以,当我在浏览TCP的时候,遇到了Nagle的算法和对小数据包(1字节数据)的延迟确认。原因是,避免在网络上发送大量小数据包(Nagle)和背载数据(延迟背载)。然而,没有提到这些针对批量数据的算法,即我写了>8000字节的数据。4个问题: 这些算法是否只适用于小数据包 例如,当我们进行写操作(8000)时,TCP首先发送1500字节(假设1500字节是MSS,并且正在发生慢启动),在收到第一个ACK之前,它可以再发送1500字节的数据,那么是否违反了Nagle的要求 接收器是等待超时发送延迟

所以,当我在浏览TCP的时候,遇到了Nagle的算法和对小数据包(1字节数据)的延迟确认。原因是,避免在网络上发送大量小数据包(Nagle)和背载数据(延迟背载)。然而,没有提到这些针对批量数据的算法,即我写了>8000字节的数据。4个问题:

  • 这些算法是否只适用于小数据包

  • 例如,当我们进行写操作(8000)时,TCP首先发送1500字节(假设1500字节是MSS,并且正在发生慢启动),在收到第一个ACK之前,它可以再发送1500字节的数据,那么是否违反了Nagle的要求

  • 接收器是等待超时发送延迟ACK,还是在接收1500字节数据后立即发送

  • 它如何知道何时延迟确认?它是否基于其接收缓冲区中的字节

  • 谢谢

  • Nagle通过套接字选项关闭。默认情况下会设置Nagle和Delayed ack。Nagle延迟传输,除非形成完整的数据包或管道中存在未确认的数据,因此,它会影响具有小数据包的应用程序受限流的性能

  • 这取决于发送模式

  • 如果接收器上已经有一个未确认的数据包,这1500字节将成为一个确认。然而,如果没有先前接收到的数据,并且接收机没有使用快速确认,则发送确认将延迟一段时间(例如200 ms),或者除非接收到下一个数据包

  • 3号会有帮助


  • Nagle的算法应该能够减少小数据包的数量(例如,它不会通过慢速链接向telnet发送每个字符的单独数据包)。如果它可以发送一个完整的数据包,它应该发送一个完整的数据包。它不违反以下内容中的描述:

    如果存在未确认的数据(即,
    SND.NXT>
    UNA
    ),则发送TCP缓冲所有用户 数据(不考虑PSH位),直到 已确认未完成的数据,或直到 TCP可以发送一个完整大小的段
    Eff.snd.MSS
    字节;见第4.2.2.6节)

    延迟的ACK减少了反向发送的数据包数量,但RFC 1122中的描述在很大程度上取决于实现:

    TCP应该实现延迟的ACK,但ACK不应该实现 拖得太久,;特别是,必须避免延误 小于0.5秒,且在全尺寸流中 至少每秒钟应该有一次确认 部分


    请注意,当您发送“大容量数据”时,接收器不是!如果它立即发送ack,它们都是小数据包,可能会有很多开销。

    Nagle算法的思想是防止一次传输多个较小的数据包。延迟ACK(来自伯克利)的想法是为了避免在通过远程echo的Telnet连接键入时,为接收到的每个字符发送一个单独的ACK,方法是等待一段固定的时间,等待反向的通信量,在该时间段上可以携带ACK

    这两种算法的交互作用非常糟糕。如果你做了大发送,大发送,大发送,效果很好。如果你真的发送,得到回复,发送,得到回复,这很好。如果你做小发送,小发送,得到回复,会有一个短暂的停顿。这是因为第二次小发送被Nagle算法延迟,直到ACK返回,而延迟的ACK算法在这之前增加0.5秒左右

    延迟确认是一种打赌。TCP实现打赌数据将很快发送,因此不必发送单独的ACK。每次实际发送延迟确认时,该赌注都会失败。TCP规范允许实现在不关闭延迟ACK的情况下每次都输掉该赌注。正确地说,只有在连续发送了几个本可以承载的不必要的ACK时,才应该启用延迟ACK,并且在实际发送延迟ACK时,应该再次关闭延迟ACK。应该有一个柜台

    不幸的是,我在1986年退出网络后,延迟的ACK就出现了,而且这个问题从未得到解决。现在太晚了


    约翰·纳格尔(John Nagle)

    那么为什么这个标签是C?您正在寻找C代码中的示例吗?默认情况下,Nagle也会启用。是。它可以通过套接字选项关闭。我见过这样的例子:4个发送段只收到1个ack,所有4个都收到ack。那么“一个完整大小的段流应该至少每秒钟有一个ACK”这句话是不是错了?或者实施方式已经改变了?@Nikhil它们是“全尺寸”的吗?还要注意的是,它也只是一个“应该”:AIUI应用程序读取数据时,典型的TCP堆栈仅确认,如果应用程序执行单个大的
    read()
    ,则没有理由发送大量确认。还要注意的是,在10Gbit网络上,一个完整大小的数据包所需时间不到2微秒;在内核可以自由处理多个数据包之前,该卡可能会缓冲多个数据包,内核也可以一次确认所有数据包。是的,它们是全尺寸的数据包。RFC中是否提到,如果TCP接收到10段并处理了它们,它只能发送一个ACK?@Nikhil它将“应该”定义为“在特定情况下,可能存在忽略此项的有效原因,但在选择不同的课程之前,应理解全部含义并仔细权衡案例”。很难知道您看到的行为是否违反了规范的精神,但我当然希望在同一中断中处理同一连接上多个数据包的系统只发送数据包