在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异? [英] Is there any significant difference between TCP_CORK and TCP_NODELAY in this use-case?

查看:129
本文介绍了在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在写了关于TCP_NODELAY和TCP_CORK的答案后,我意识到我对TCP_CORK的优点的认识一定不足我尚不清楚100%为什么Linux开发人员认为有必要引入一个新的TCP_CORK标志,而不是仅仅在适当的时间依赖该应用程序设置或清除现有的TCP_NODELAY标志.

After writing an answer about TCP_NODELAY and TCP_CORK, I realized that my knowledge of TCP_CORK's finer points must be lacking, since it's not 100% clear to me why the Linux developers felt it necessary to introduce a new TCP_CORK flag, rather than just relying on the application to set or clear the existing TCP_NODELAY flag at the appropriate times.

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

In particular, if I have a Linux application that wants to send() some small/non-contiguous fragments of data over a TCP stream without paying the 200mS Nagle latency-tax, and at the same time minimize the number of packets needed to send it, I can do it either of these two ways:

使用TCP_CORK(伪代码):

With TCP_CORK (pseudocode):

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(伪代码):

or with TCP_NODELAY (pseudocode):

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()的零字节就足够了.)

I've been using the latter technique for years with good results, and it has the benefit of being portable to non-Linux OS's as well (although outside of Linux you have to call send() again after turning Nagle's back off, in order to ensure the packets get sent immediately and avoid the Nagle-delay -- send()'ing zero bytes is sufficient).

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

Now the Linux devs are smart guys, so I doubt that the above usage of TCP_NODELAY never occurred to them. There must be some reason why they felt it was insufficient, which led them to introduce a new/proprietary TCP_CORK flag instead. Can anybody explain what that reason was?

推荐答案

您有两个问题:

  1. 在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?
  2. 由于某些原因,他们认为它不够用,这导致他们引入了一个新的专有TCP_CORK标志.谁能解释这个原因是什么?

首先在此 Stack Overflow Question (堆栈溢出问题),因为涉及到该问题,因为该问题通常描述了两者之间的差异,而没有引用您的用例.

First see the answers in this Stack Overflow Question, because the are related in the since that question generally describes the difference between the two without reference to your usecase.

  • TCP_NODELAY ON 意味着在您收到数据后立即发送数据(部分帧),无论您是否有足够的帧来容纳完整的网络数据包.
  • TCP_NODELAY OFF 表示Nagles Algoritm,这意味着当数据大于MSS时发送数据,或者在发送较小的数据之前等待接收确认.
  • TCP_CORK ON 表示在应用程序发出此消息之前或直到200ms之后,才发送小于MSS的任何数据(部分帧).
  • TCP_CORK OFF 表示立即发送所有数据(部分帧).
  • TCP_NODELAY ON means send the data (partial frames) the moment you get, regardless if you have enough frames for a full network packet.
  • TCP_NODELAY OFF means Nagles Algoritm which means send the data when it is bigger than the MSS or waiting for the receiving acknowledgement before sending data which is smaller.
  • TCP_CORK ON means don't send any data (partial frames) smaller than the MSS until the application says so or until 200ms later.
  • TCP_CORK OFF means send all the data (partial frames) now.

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

This means in your given use case in the first example no partial frames are sent until the end, but in your second example partial frames with a receiving acknowledgement will be sent.

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

Also the final send in your first example , Nagle's algorithm still applies to the partial frames after the uncorking , where as in the second example it doesn't.

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

The short version is the TCP_NODELAY sends doesn't accumulate the logical packets before sending then as network packets, Nagle's algorithm does according the algorithm, and TCP_CORK does according to the application setting it.

此方法的副作用是Nagle的算法将在空闲连接上发送部分帧,而TCP_CORK不会.

A side effect of this is that Nagle's algorithm will send partial frames on an idle connection, TCP_CORK won't.

另外,TCP_CORK在2.2中引入了Linux内核(特别是2.1.127,请参见

Additionally TCP_CORK was introduced into the Linux Kernel in 2.2 (specifically 2.1.127 see here), but until 2.5.71 it was mutually exclusive with TCP_NODELAY. E.g In 2.4 kernels you could use one or the other, but in 2.6 you can combine the two, and TCP_CORK will take precedence when it is applied.

关于第二个问题.

引用Linus Torvalds

To quote Linus Torvalds

现在,TCP_CORK基本上是我告诉David Miller我拒绝玩 游戏具有良好的数据包大小分布,我想要一种方法 该应用程序只是告诉操作系统:我想要大数据包,请等到 您从我那里获得了足够的数据,可以制造大数据包.

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.

基本上,TCP_CORK是一种"anti-nagle"标志.这是相反的 不戴眼镜".

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

Linus的另一句话是关于TCP_CORK的用法,

Another quote also by Linus is regarding usage of TCP_CORK is the following

基本上,只要服务器知道以下模式,TCP_CORK就很有用 它的批量转移.使用任何一种方式,大约只有100%的时间 文件投放.

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邮件列表讨论"的链接.

For more quotes see the link with Sendfile Mailing List Discussion.

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

In summary, in addition to TCP_MAXSEG and MSGMORE when calling writev, TCP_CORK is another tool which allows the application in userspace to have more fine grained control over packet size distribution.

参考文献和进一步阅读

  • Earthquaky kernel interfaces
  • Sendfile Kernel Mailing Discussion (where the quote comes from)
  • TCP/IP options for high-performance data transmission
  • Rethinking the TCP Nagle Algorithm
  • TCP_CORK: More than you ever wanted to know
  • The C10K problem
  • TCP man page
  • The Linux Programming Interface Page 1262

这篇关于在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆