在写完关于TCP_NODELAY和TCP_CORK的答案之后,我意识到我必须缺少对TCP_CORK的要点的了解,因为我尚不清楚100%为何Linux开发人员认为有必要引入一个新的TCP_CORK标志,而不是仅仅依靠应用程序在适当的时间设置或清除现有的TCP_NODELAY标志。
特别是,如果我有一个Linux应用程序想要通过TCP流send()一些小/非连续的数据片段,而无需支付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操作系统(尽管在Linux外部,您必须在关闭Nagle的关闭后再次调用send())以确保立即发送数据包并避免Nagle延迟-
send()为零字节就足够了)。
现在,Linux开发人员很聪明,所以我怀疑他们对TCP_NODELAY的上述使用从未发生过。他们一定有某种理由感到不足,这导致他们引入了新的专有TCP_CORK标志。谁能解释这个原因是什么?