Linux 我应该在什么时候使用TCP_节点延迟,什么时候使用TCP_软木塞?

Linux 我应该在什么时候使用TCP_节点延迟,什么时候使用TCP_软木塞?,linux,sockets,tcp,Linux,Sockets,Tcp,我知道他们都禁用了Nagle的算法 我什么时候应该/不应该使用它们中的每一个?这是一种优化,因此与任何优化一样: 不要使用它 等到性能出现问题,然后确定套接字延迟肯定是导致问题的原因,测试证明这肯定会解决问题,这是解决问题的最简单方法,去做吧 基本上,目的是避免使用sendfile()和它的朋友发送多个可以使用单个帧的帧 例如,在一个web服务器中,您发送头,然后是文件内容,头将在内存中组装,然后文件将由内核直接发送。TCP_CORK允许在单个帧中发送文件的头和开头,即使使用TCP_NODELA

我知道他们都禁用了Nagle的算法


我什么时候应该/不应该使用它们中的每一个?

这是一种优化,因此与任何优化一样:

  • 不要使用它
  • 等到性能出现问题,然后确定套接字延迟肯定是导致问题的原因,测试证明这肯定会解决问题,这是解决问题的最简单方法,去做吧
  • 基本上,目的是避免使用sendfile()和它的朋友发送多个可以使用单个帧的帧


    例如,在一个web服务器中,您发送头,然后是文件内容,头将在内存中组装,然后文件将由内核直接发送。TCP_CORK允许在单个帧中发送文件的头和开头,即使使用TCP_NODELAY,也会导致第一个块立即发送。

    TCP_CORK与TCP_NODELAY相反。前者强制分组累积延迟;后者会禁用它。

    首先,并非两者都会禁用Nagle的算法

    Nagle的算法是为了减少网络中更多的小数据包。算法是:如果数据小于限制(通常是MSS),则等待接收到之前发送的数据包的ACK,同时从用户处累积数据。然后发送累积的数据

    if [ data > MSS ]
        send(data)
    else
        wait until ACK for previously sent data and accumulate data in send buffer (data)
        And after receiving the ACK send(data)
    

    这将有助于像telnet这样的应用程序。然而,等待ACK可能会增加发送流数据时的延迟。此外,如果接收方实现“延迟确认策略”,则将导致临时死锁情况。在这种情况下,禁用Nagle算法是更好的选择

    因此,TCP_节点用于禁用Nagle算法

    TCP_CORK积极地积累数据。如果在套接字中启用TCP_CORK,则在缓冲区填充到固定限制之前,它不会发送数据。与Nagle的算法类似,它也会从用户处累积数据,但直到缓冲区填充到固定限制为止,直到收到ACK为止。这在发送多个数据块时非常有用。但在使用TCP_软木塞时,您必须更加小心

    在2.6内核之前,这两个选项是互斥的。但在以后的内核中,它们可以同时存在。在这种情况下,TCP_软木塞将获得更多的优先权

    参考:


      • TCP\u节点延迟

        用于禁用Nagle的算法,以改进TCP/IP网络,并通过等待收到先前发送数据的确认来发送累积数据包,从而减少数据包的数量

        //从tcp(7)手册:

        TCP\u-CORK
        (或FreeBSD中的
        TCP\u-NOPUSH


        如果已设置,则不发送部分帧。再次清除该选项时,将发送所有排队的部分帧。这对于在调用
        sendfile(2)
        之前预编标头或吞吐量优化非常有用。按照目前的实施,输出被
        TCP\u CORK
        阻塞的时间有**200毫秒上限**如果达到此上限,则自动传输排队数据。仅在Linux 2.5.71之后,此选项才能与TCP_节点延迟结合使用。此选项不应用于可移植的代码。

        Nagle本身是一种优化,因此根据您的逻辑,您应该将其关闭,并仅在需要时将其打开:-)Nagle在默认情况下处于启用状态,您不需要编写任何代码来启用它,因此它无论如何都会发生。不,如果您正在编写自己的TCP堆栈,如果您不需要实现Nagle,您就不会这么做。如果在几年后真的发生了这种情况(有人不再实现它),我也不会感到惊讶。大约30年或40年前,人们主要担心的是,人们在telnet上以每秒大约2个字符的速度打字会为每个字符生成一个数据包。如今,带宽更高,远程登录在流量方面没有扮演重要角色,而且几乎所有远程登录流量都使用了块密码,这几乎不是一个问题。使用128位分组密码无法发送少于16字节的数据(无论如何,如果你想在另一端对其进行解码,则无法发送)。@camh我知道你在开玩笑,但为了保护OP,禁用Nagle的行为有时是对延迟变量的优化。@camh老实说,我一开始读马克的建议是“使用NODELAY直到你确定你需要延迟”正是因为在我看来,Nagle是“优化”。在这种情况下,这绝对是一个模糊的建议。感谢你指出许多指南完全错误的地方,TCP_CORK只延迟200ms(最大值)实际上,它并不是一个软木塞,除非移除它才能堵塞。
        TCP_-CORK
        不是
        TCP_-NODELAY
        的对立面。Nagle的算法在等待返回确认时聚合数据,后者选项禁用;前者根据缓冲压力聚合数据。记住Hussein Galal的回答,该回答澄清了TCP_-CORK在发送数据之前最多只能延迟200毫秒。”这将有助于像telnet这样的应用程序。"? 事实恰恰相反。如果您按下一个键,这将延迟将您的按键发送到另一侧,直到收到最后一次按键的确认。这在按键和按键发送之间引入了高延迟,我不知道在什么情况下需要这样做。