- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在写了一个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 标志。谁能解释一下这是什么原因?
最佳答案
你有两个问题:
先看这个Stack Overflow Question中的答案,因为它们是相关的,因为该问题通常描述了两者之间的区别,而不引用您的用例。
这意味着在第一个示例的给定用例中,直到最后才发送部分帧,但在第二个示例中,将发送带有接收确认的部分帧。
也是您第一个示例中的最终发送,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/
我有一个用例,我在一个方向上通过 TCP/IP 发送数据。我通过多个 send() 调用来执行此操作,这些调用具有非常小的(相对于以太网帧的大小)有效负载(没有任何 send() 标志-称呼)。为了防
在许多 UNIX TCP 实现中,提供了一个套接字选项 TCP_CORK ,它允许调用者绕过 Nagle's algorithm 并明确指定何时发送物理数据包。 Windows (Winsock) 中
我知道他们都禁用了 Nagle 的算法。 什么时候应该/不应该使用它们中的每一个? 最佳答案 首先,并非两者都禁用了 Nagle 算法。 Nagle 的算法用于减少线路中更多的小型网络数据包。该算法是
我正在使用 java 7、java nio 来构建我的应用程序。我不知道如何在 java 代码中设置 TCP_CORK 选项。我只看到 TCP_NODELAY、SO_SNDBUF... 选项。请告诉我
在写了一个answer之后关于 TCP_NODELAY 和 TCP_CORK,我意识到我一定缺乏对 TCP_CORK 细节的了解,因为我不是 100% 清楚为什么 Linux 开发人员觉得有必要引入一
我的文件系统中有小文件和大文件(8k 到 100 GB)的组合。我需要使用 c 中的套接字编程通过 1GB 的网络(具有 4 个套接字)传输它们,以使用大部分网络。 我设置了选项 tcp_cork 和
我是一名优秀的程序员,十分优秀!