一尘不染

在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?

linux

在写完关于TCP_NODELAY和TCP_CORK的答案之后,我意识到我必须缺少对TCP_CORK的要点的了解,因为我尚不清楚100%为何Linux开发人员认为有必要引入一个新的TCP_CORK标志,而不是仅仅依靠应用程序在适当的时间设置或清除现有的TCP_NODELAY标志。

特别是,如果我有一个Linux应用程序想要通过TCP流send()一些小/非连续的数据片段,而无需支付200mS
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延迟-
send()为零字节就足够了)。

现在,Linux开发人员很聪明,所以我怀疑他们对TCP_NODELAY的上述使用从未发生过。他们一定有某种理由感到不足,这导致他们引入了新的专有TCP_CORK标志。谁能解释这个原因是什么?


阅读 419

收藏
2020-06-07

共1个答案

一尘不染

您有两个问题:

  1. 在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?
  2. 他们一定有某种理由感到不足,这导致他们引入了新的专有TCP_CORK标志。谁能解释这个原因是什么?

  3. TCP_NODELAY ON 表示在您获取数据后立即发送数据(部分帧),而不管您是否有足够的帧容纳完整的网络数据包。

  4. TCP_NODELAY OFF 表示Nagles Algoritm,表示大于MSS时发送数据,或者在发送较小的数据之前等待接收确认。
  5. TCP_CORK ON 表示直到应用程序发出此消息或直到200ms之后才发送小于MSS的任何数据(部分帧)。
  6. TCP_CORK OFF 表示立即发送所有数据(部分帧)。

这意味着在第一个示例的给定用例中,直到结束都不会发送部分帧,但是在第二个示例中,将发送带有接收确认的部分帧。

同样,在您的第一个示例中,最后一次发送Nagle的算法仍然适用于拔瓶后的部分帧,而在第二个示例中则不适用。

简短的版本是TCP_NODELAY发送时不会在发送之前累积逻辑数据包,然后将其作为网络数据包,Nagle的算法根据算法进行操作,TCP_CORK根据应用程序对其进行设置。

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

另外,TCP_CORK在2.2(特别是2.1.127,请参阅此处)中引入了Linux内核,但是直到2.5.71,它与TCP_NODELAY互斥。例如,在2.4内核中,您可以使用其中之一,但在2.6中,您可以将两者结合使用,并且在应用TCP_CORK时会优先使用。

关于第二个问题。

引用莱纳斯·托瓦尔兹(Linus Torvalds)

现在,TCP_CORK基本上是告诉我大卫米勒,我拒绝玩游戏以具有良好的数据包大小分布,并且我想让应用程序仅告诉操作系统一种方法:我想要大数据包,请等待,直到从中获取足够的数据为止。我可以做成大包。

基本上,TCP_CORK是一种“ anti-nagle”标志。这是“无-”的反面。

Linus的另一句话是关于TCP_CORK的用法,如下所示

基本上,只要服务器知道其批量传输的模式,TCP_CORK就会很有用。使用任何类型的文件服务,这几乎都是100%的时间。

有关更多报价,请参见“ Sendfile邮件列表讨论”的链接。

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

2020-06-07