在写了一个关于 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 延迟——发送()'ing 零字节就足够了)。
现在 Linux 开发人员都是聪明人,所以我怀疑他们从来没有想到过 TCP_NODELAY 的上述用法。一定有他们觉得它不够的原因,这导致他们引入了一个新的/专有的 TCP_CORK 标志。任何人都可以解释那个原因是什么?