- 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_NODELAY,如下所示: fd = accept(listener, (struct sockaddr *)&sin, &slen); if (fd FD_SET
我有一个使用 TCP 从设备读取数据包的应用程序。我想知道我的接收方应用程序是否使用 TCP_NODELAY 选项创建套接字,设备会自动开始发送数据包而不缓冲它们,还是我必须在发送方(设备)上进行此更
我正在使用 Boost asio 发送 TCP 消息。我设置了 NO_DELAY 选项,因为这是一个“实时”控制系统。我看到使用 Wireshark 在消息中设置了 PSH 标志。我对性能感到满意,并
根据我对 Nagel 算法的理解,如果可能的话,它会尝试在一条消息中发送多条消息,以使用更少的带宽。 我的问题是,对于一个大学项目,我必须禁用它;我必须首先发送一个名称,然后发送年、月、日,最后发送文
我正在编写一个 c 程序,它通过 tcp 连接发送 bash shell 的输出。为了使我的程序更具响应性,我使用 setsockopt() 来启用 TCP_NODELAY,这会禁用 Nagle 的缓
我一直认为 Nagle 的算法会在两个方向影响套接字,并且设置 TCP_NODELAY 以某种方式通知远程端也关闭 Nagle。 是这样吗,还是设置 TCP_NODELAY 只影响调用它的那一端的行为
我正在诊断一个奇怪的网络问题,(我认为)我已经缩小到行为不当的 HTTP 客户端或服务器以及一些 HTTP1.1 流水线和/或 Nagle 的算法交互。我试图在 curl 中禁用 TCP_NODELA
我正在诊断一个奇怪的网络问题,(我认为)我已经缩小到行为不当的 HTTP 客户端或服务器以及一些 HTTP1.1 流水线和/或 Nagle 的算法交互。我试图在 curl 中禁用 TCP_NODELA
我正在尝试在 Ubuntu 16.04 中编译 ChatScipt v7.55。但是当我使用 make server 命令时,我得到了这个错误: evserver.cpp: In function ‘
TCP_NODELAY 和 MSG_DONWAIT 有什么区别?我知道一个是特定于 TCP 的,另一个是发送时的通用套接字选项,但这两个选项是否有行为不同场景下的不同? 就像TCP_NODELAY一样
我正在尝试在 unix 域套接字上设置标志 tcp_nodelay。我们可以设置它还是为 UNIX 域套接字设置 tcp_nodelay 是否有意义,特别是在 Linux 上? 请指教。 谢谢 最佳答
如果我用 TCP_NODELAY 创建一个 TCP 套接字启用选项并将其用于listen对于新连接,accept 会返回新套接字吗?还有TCP_NODELAY启用? 不同的套接字可以有不同的配置选项,
TCP_NODELAY 是一个启用快速发送 TCP 数据包的选项,无论它们的大小如何。当速度很重要时,这是非常有用的选项,但是,我很好奇它会对此做什么: Socket socket = [some s
我最近在运行一些比较网络性能与环回性能的性能测试时偶然发现了一个有趣的 TCP 性能问题。在我的例子中,网络性能超过了环回性能(1Gig 网络,相同的子网)。在我处理延迟的情况下,延迟是至关重要的,因
如果您在套接字上的每个调用上设置 TCP_QUICKACK 设置,之前设置了 TCP_NODELAY,QUICKACK 选项是否会覆盖 NODELAY 调用? 连接时: int i = 1; sets
我试图通过设置 TCP_NODELAY 在 Ubuntu Linux 机器上使用我的 TCP 套接字禁用 Nagle 算法范围。由于某种原因, 中未定义此常量。或 .这个常量是否已被弃用,然后从 L
我知道他们都禁用了 Nagle 的算法。 什么时候应该/不应该使用它们中的每一个? 最佳答案 首先,并非两者都禁用了 Nagle 算法。 Nagle 的算法用于减少线路中更多的小型网络数据包。该算法是
我试图通过在设置后回读它来验证我的 TCP_NODELAY 设置是否有效。 我将值设置为“1”,但当我读回它时,它设置为“4”。恐怕我做错了什么。 这是我的代码: int tcpBefore;
我正在使用 Scala 的远程参与者,但往返时间(即使是一条微不足道的消息)是 80 毫秒,大概是由于底层套接字没有禁用 TCP/IP Nagle 算法(也称为 TCP_NODELAY),或者至少这是
在写了一个answer之后关于 TCP_NODELAY 和 TCP_CORK,我意识到我一定缺乏对 TCP_CORK 细节的了解,因为我不是 100% 清楚为什么 Linux 开发人员觉得有必要引入一
我是一名优秀的程序员,十分优秀!