在这个用例中,TCP_CORK和TCP_NODELAY之间有什么明显的区别吗?

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

特别是,如果我有一个Linux应用程序希望通过TCPstream发送()一些小的/非连续的数据片段,而不需要支付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操作系统的好处(尽pipe在Linux之外,您必须在将Nagle退后之后再次调用send()以确保数据包立即发送并避免Nagle延迟 – send()只需零字节即可)。

现在的Linux开发人员都是聪明人,所以我怀疑TCP_NODELAY的上述用法从来没有出现过。 为什么他们觉得自己不够用呢,这就导致他们引入一个新的/专有的TCP_CORK标志。 有人可以解释是什么原因?

Solutions Collecting From Web of "在这个用例中,TCP_CORK和TCP_NODELAY之间有什么明显的区别吗?"

你有两个问题:

  1. 在这个用例中,TCP_CORK和TCP_NODELAY之间有什么明显的区别吗?
  2. 为什么他们觉得自己不够用呢,这就导致他们引入一个新的/专有的TCP_CORK标志。 有人可以解释是什么原因?

首先看到这个堆栈溢出问题的答案,因为这个问题相关,因为这个问题通常描述两者之间的差异,而不涉及到你的用例。

  • TCP_NODELAY ON意味着在你得到的那一刻发送数据(部分帧),而不管你是否有足够的帧用于完整的网络数据包。
  • TCP_NODELAY OFF表示Nagles Algoritm,意思是发送大于MSS的数据或等待接收确认,然后发送较小的数据。
  • TCP_CORK ON表示不发送小于MSS的任何数据(部分帧),直到应用程序如此说明或直到200ms之后。
  • TCP_CORK OFF表示现在发送所有的数据(部分帧)。

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

也是在你的第一个例子中的最后一个发送,Nagle的算法仍然适用于开盖之后的部分帧,在第二个例子中,它不是。

短版本是TCP_NODELAY发送之前不发送逻辑包,然后作为网络包发送,Nagle的算法按照算法做,而TCP_CORK根据应用程序的设置做。

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

另外,TCP_CORK被引入到2.2版的Linux内核中(特别是2.1.127见这里 ),但直到2.5.71它与TCP_NODELAY互斥。 例如,在2.4内核中,您可以使用其中一种,但是在2.6中可以将两者结合使用,TCP_CORK在应用时将优先使用。

关于你的第二个问题。

引用Linus Torvalds

现在,TCP_CORK基本上是告诉David Miller,我拒绝玩游戏,以便拥有良好的数据包大小分布,并且我希望让应用程序告诉操作系统:我想要大数据包,请等待,直到获得足够的数据我可以做大包。

基本上,TCP_CORK是一种“反老鹰”的旗帜。 这是“no-nagle”的反面。

Linus的另一个引用是关于TCP_CORK的使用如下

基本上,只要服务器知道批量传输的模式,TCP_CORK就很有用。 这只是100%的时间与任何形式的文件服务。

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

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

参考和进一步阅读

  • Earthquaky内核接口
  • Sendfile内核邮件讨论(引用来自哪里)
  • 用于高性能数据传输的TCP / IP选项
  • 重新思考TCP Nagle算法
  • TCP_CORK:超过你想知道的
  • C10K的问题
  • TCP手册页
  • Linux编程接口页面1262