gpt4 book ai didi

linux - 在此用例中,TCP_CORK 和 TCP_NODELAY 之间是否存在显着差异?

转载 作者:IT王子 更新时间:2023-10-29 00:22:03 24 4
gpt4 key购买 nike

在写了一个answer之后关于 TCP_NODELAY 和 TCP_CORK,我意识到我一定缺乏对 TCP_CORK 细节的了解,因为我不是 100% 清楚为什么 Linux 开发人员觉得有必要引入一个新的 TCP_CORK 标志,而不是仅仅依靠应用程序来设置或在适当的时候清除现有的 TCP_NODELAY 标志。

特别是,如果我有一个 Linux 应用程序想要通过 TCP 流发送()一些小的/非连续的数据片段,而无需支付 200 毫秒的 Nagle 延迟税,同时最小化数据包的数量需要发送它,我可以通过以下两种方式之一进行发送:

使用 TCP_CORK(伪代码):

int optval = 1;
setsockopt(sk, SOL_TCP, TCP_CORK, &optval, sizeof(int)); // put a cork in it
send(sk, ..);
send(sk, ..);
send(sk, ..);
optval = 0;
setsockopt(sk, SOL_TCP, TCP_CORK, &optval, sizeof(int)); // release the cork

或使用 TCP_NODELAY(伪代码):

int optval = 0;
setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); // turn on Nagle's
send(sk, ..);
send(sk, ..);
send(sk, ..);
optval = 1;
setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); // turn Nagle's back off

多年来我一直在使用后一种技术并取得了良好的效果,并且它还具有可移植到非 Linux 操作系统的好处(尽管在 Linux 之外你必须在关闭 Nagle 后再次调用 send() ,以确保立即发送数据包并避免 Nagle 延迟——发送()的零字节就足够了)。

现在 Linux 开发人员都是聪明人,所以我怀疑他们从来没有想过 TCP_NODELAY 的上述用法。一定有一些原因让他们觉得它不够用,这导致他们引入了一个新的/专有的 TCP_CORK 标志。谁能解释一下这是什么原因?

最佳答案

你有两个问题:

  1. 在此用例中,TCP_CORK 和 TCP_NODELAY 之间是否存在显着差异?
  2. 一定有一些原因让他们觉得它不够用,这导致他们引入了一个新的/专有的 TCP_CORK 标志。谁能解释一下原因是什么?

先看这个Stack Overflow Question中的答案,因为它们是相关的,因为该问题通常描述了两者之间的区别,而不引用您的用例。

  • TCP_NODELAY ON 表示在收到数据时立即发送数据(部分帧),无论您是否有足够的帧来容纳完整的网络数据包。
  • TCP_NODELAY OFF 表示 Nagles Algoritm,即当数据大于 MSS 时发送数据或在发送小于 MSS 的数据之前等待接收确认。
  • TCP_CORK ON 表示不发送任何小于 MSS 的数据(部分帧),直到应用程序这样说或直到 200 毫秒后。
  • TCP_CORK OFF 表示现在发送所有数据(部分帧)。

这意味着在第一个示例的给定用例中,直到最后才发送部分帧,但在第二个示例中,将发送带有接收确认的部分帧。

也是您第一个示例中的最终发送,Nagle 的算法仍然适用于开塞后的部分帧,而在第二个示例中则不适用。

简而言之就是TCP_NODELAY发送前不累积逻辑包然后作为网络包发送,Nagle算法按照算法做,TCP_CORK按照应用设置做。

这样做的副作用是 Nagle 算法将在空闲连接上发送部分帧,而 TCP_CORK 不会。

另外,TCP_CORK 在 2.2 中引入了 Linux 内核(具体 2.1.127 参见 here ),但直到 2.5.71 才与 TCP_NODELAY 互斥。例如,在 2.4 内核中,您可以使用其中之一,但在 2.6 中,您可以将两者结合使用,并且在应用时 TCP_CORK 将优先。

关于你的第二个问题。

引用 Linus Torvalds 的话

Now, TCP_CORK is basically me telling David Miller that I refuse to play games to have good packet size distribution, and that I wanted a way for the application to just tell the OS: I want big packets, please wait until you get enough data from me that you can make big packets.

Basically, TCP_CORK is a kind of "anti-nagle" flag. It's the reverse of "no-nagle".

Linus 的另一段引述是关于 TCP_CORK 的用法如下

Basically, TCP_CORK is useful whenever the server knows the patterns of its bulk transfers. Which is just about 100% of the time with any kind of file serving.

有关更多引述,请参阅 Sendfile 邮件列表讨论链接。

总而言之,在调用 writev 时,除了 TCP_MAXSEG 和 MSGMORE 之外,TCP_CORK 是另一个允许用户空间中的应用程序对数据包大小分布进行更细粒度控制的工具。

引用和进一步阅读

关于linux - 在此用例中,TCP_CORK 和 TCP_NODELAY 之间是否存在显着差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22124098/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com