如何在 Linux 中禁用 Nagle 算法? [关闭]

Posted

技术标签:

【中文标题】如何在 Linux 中禁用 Nagle 算法? [关闭]【英文标题】:How would one disable Nagle's algorithm in Linux? [closed] 【发布时间】:2013-07-24 10:11:18 【问题描述】:

有没有办法通过命令行来做到这一点? man tcp 告诉我需要设置 tcp_nodelay=1,但是我无法在 /proc/sys/net/ipv4 下创建 tcp_nodelay 文件。如果有任何方法可以在 Linux 中禁用 Nagle,请告诉我。

【问题讨论】:

您希望这是系统范围的吗? 是的,理想情况下我希望它在系统范围内 【参考方案1】:

此标志 (TCP_NODELAY) 是一个可以在每个套接字基础上启用的选项,并在您创建 TCP 套接字时应用。这样做是有目的的:Nagle 的算法通常很有用并且有助于处理网络拥塞。我怀疑您是否想在系统范围内禁用它,因为您的系统可能会受到这种停用的影响。

要为给定的套接字禁用它,您可以应用选项 TCP_NODELAY,如 C 中的 here 和 here 所述:

int flag = 1;
int result = setsockopt(sock,            /* socket affected */
                        IPPROTO_TCP,     /* set option at TCP level */
                        TCP_NODELAY,     /* name of option */
                        (char *) &flag,  /* the cast is historical cruft */
                        sizeof(int));    /* length of option value */
 if (result < 0)
    ... handle the error ...

您可能必须适应您的编程语言,但基本上它将TCP_NODELAY 标志选项设置为套接字sock,从而有效地禁用了Nagle 算法。这在任何带有支持 TCP 标准的套接字的操作系统上都有效。

如果您仍想在系统范围内禁用 Nagle 算法,有两个选项可用。首先,您可以使用相应的标志重新编译您的内核(请参阅您的发行手册)。第二种选择是创建一个在每个现有连接上设置TCP_NODELAY 标志的软件,类似于this code。每次在系统上创建新的 TCP 连接时,都应执行后一个选项。

激活 TCP 的低延迟模式会更简洁:

echo 1 > /proc/sys/net/ipv4/tcp_low_latency

更新:在内核 v4.14 及更高版本中删除了 tcp_low_latency。

这将提示 TCP 堆栈做出哪些决定以降低延迟(我猜这就是您试图通过禁用 Nagle 算法来实现的目标)。默认设置为优化带宽(“0”将从/proc/sys/net/ipv4/tcp_low_latency读取)。

【讨论】:

你的答案是正确的,但你为什么要把&amp;flag 转换成char *setsockopt 需要一个 const void * 值指针,因此不需要转换为类型(每种类型都可以隐式转换为 void *):pubs.opengroup.org/onlinepubs/9699919799/functions/… 实际上你甚至违反了 C 标准,因为将类型 A 的指针转换为B 类型的指针,其中两个类型都不是 void * 实际上是 ISO-C 未定义的行为。您有一个指向 int 的指针,但您声称它是指向 char * 的指针(几乎适用于所有系统,但在技术上未定义) 这段代码不是我的,而是我所说的复制粘贴第二个链接。您可能想联系 www.unixguide.net 了解此问题。我记得看到setsockopt() 有几个不同的签名,其中一些(如我提供的第一个链接)使用char * 作为flag 参数。我不介意更改答案,只要引用可靠的setsockopt() 原型和执行所需操作的代码示例即可。 同意 Soravux :来自 Microsoft MSDN: int setsockopt( SOCKET s, int level, int optname, const char *optval, int optlen );来自 linux 手册页 int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);来自 vxWorks socklib STATUS setsockopt ( int s, int level, int optname, char * optval, int optlen) 和来自 IBM aix 7.1 int setsockopt (Socket, Level, OptionName, OptionValue, OptionLength) int Socket, Level, OptionName;常量无效 * 选项值; socklen_t OptionLength; 请注意,从内核 v4.14 开始,tcp_low_latency 不再做任何事情。 github.com/torvalds/linux/commit/…

以上是关于如何在 Linux 中禁用 Nagle 算法? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

TCP之Nagle算法与TCP_NODELAY

nagle算法和TCP_NODELAY

TCP Nagle算法以及延迟确认(即延迟回复ACK)的学习

Nagle算法

socket.setNoDelay([noDelay]) 用的是Nagle算法

delayed ack与nagle's算法