何时对 TcpClient 禁用 Nagle 算法?

问题描述 投票:0回答:1

来自文档

当 NoDelay 为 false 时,TcpClient 不会通过 网络,直到收集到大量传出数据。 由于 TCP 段中的开销量,发送小 数据量大,效率低下。然而,确实存在这样的情况:您 需要发送非常少量的数据或期望立即响应 从您发送的每个数据包中。您的决定应该权衡相关因素 网络效率与应用程序需求的重要性。

  1. 在这种情况下有多少字节符合

    small amounts of data

  2. 根据我的理解,如果您有一个

    NetworkStream
    ,每个请求从
    TcpClient
    写入一次TCP流(即不是以循环或分块方式),然后立即刷新,那么
    NoDelay
    并不重要,基于约翰·内格尔的回应。当
    NoDelay
    未设置写入时,DotNet 中的延迟是多少?

    这仍然让我烦恼。真正的问题不是tinygram的预防。它是 ACK 延迟,还有那个愚蠢的固定计时器。他们都进入了TCP 大约在同一时间,但独立。我做了tinygram预防 (Nagle 算法)和 Berkeley 确实延迟了 ACK,两者都在早期 20 世纪 80 年代。两者的结合是可怕的。不幸的是到时候 我发现了延迟的 ACK,我换了工作,脱离了网络, 并在非联网 PC 上为 Autodesk 开发产品。延迟的 ACK 仅在某些情况下才是胜利 - 主要是角色回声 远程登录。 (当伯克利安装延迟 ACK 时,他们做了很多 从学生终端室的终端集中器到 Telnet 主机 VAX 机器进行工作。针对这种特殊情况, 是有道理的。)延迟的 ACK 定时器被缩放到预期的人类 响应时间。延迟的 ACK 是指另一端会回复的赌注 您刚刚发送的内容几乎是立即发送的。除了一些RPC协议之外, 这不太可能。所以ACK延迟机制输了赌注,结束了 结束,延迟 ACK,等待可以收到 ACK 的数据包 捎带,没有收到,然后发送 ACK,延迟了。 TCP 中没有任何内容可以自动关闭此功能。然而,Linux (我认为 Windows)现在有一个 TCP_QUICKACK 套接字选项。转动那个 除非您有非常不寻常的应用程序。

    开启 TCP_NODELAY 有类似的效果,但可以使吞吐量 对于小写入来说更糟。如果你编写一个只发送一些数据的循环 使用“write()”将字节(最坏情况,一个字节)发送到套接字,并且 Nagle 使用 TCP_NODELAY 禁用算法,每次写入都会变成一个 IP 包。这使 IP 和 TCP 的流量增加了 40 倍 每个有效负载的标头。 Tinygram 预防不会让您发送 第二个数据包(如果您在飞行中有一个数据包),除非您有足够的数据 填充最大尺寸的数据包。它累积一轮的字节数 行程时间,然后发送队列中的所有内容。几乎总是这样 你想要什么。如果设置了 TCP_NODELAY,则需要做更多 了解缓冲和刷新问题。

    这些对于批量单向传输来说都不重要,这是大多数 HTTP 今天。 (我从来没有研究过这对 SSL 握手的影响, 这可能很重要。)

    简短版本:设置 TCP_QUICKACK。如果你发现这样的情况 事情更糟,请告诉我。

    约翰·内格尔

  3. NoDelay
    在发送方发送时,接收方还可以进行哪些其他与 TCP 相关的优化,以在低延迟环境中尽可能高效地接收小尺寸数据(500 字节 - 2 KB)?

c# sockets tcpclient nagle
1个回答
0
投票
  1. 归结为数据是否大于MTU(TCP发送数据包大小)。如果数据多于此(或者没有未确认的已发送数据包),则将立即发送数据,否则将进行缓冲,直到达到 MSS。 MSS 通常为 1500 字节,扣除 40 字节的开销后,MTU 为 1460 字节。

  2. 不,这是不正确的。

    NetworkStream.Flush
    什么也没做:

    Flush
    方法实现了
    Stream.Flush
    方法;但是,由于
    NetworkStream
    没有缓冲,因此对网络流没有影响。调用
    Flush
    方法不会引发异常。

    所以你调用它没有什么区别。除非使用

    TCP_NODELAY
    禁用,否则将使用 Nagles 算法。

  3. 除了平常没有什么:

    • 使用预先创建的池缓冲区。
    • 使用
      async
      代码。
    • 将读取任务交给另一个线程或线程池,而不是 UI 线程,这需要额外的同步和编组。

至于您的引用:

TCP_QUICKACK
很可能比
TCP_NODELAY
更好,但我建议您根据您的典型用法进行测试。

© www.soinside.com 2019 - 2024. All rights reserved.