tcp_cork和tcp_autocorking之间的实际区别是什么?
它只是tcp_cork的自动化版本吗?我找不到任何有价值的信息,除了这个链接:http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f54b311142a92ea2e42598e347b84e1655caf8e3。
简短回答:TCP_CORK是一种套接字选项,用于强制TCP延迟发送。tcp_autocorking是内核的一个标志,用于检查特定条件,并在满足这些条件时进行聚合。
底线:启用TCP_CORK时,每个数据包都会被延迟发送,当tcp_autocorking启用且TCP_CORK禁用时,可能对数据包进行延迟发送,如果两个选项都禁用,则不会对任何数据包进行延迟发送。即使两个选项都禁用,如果启用了Nagle算法,则仍可能进行数据聚合。
更多细节:TCP_CORK在这篇文章中有详细描述(并受到批评):on TCP_CORK。
另请参阅Appleman1234的关于TCP_CORK和TCP_NODELAY的详细说明。
通过强制TCP_CORK,数据将被聚合到同一个缓冲区(SKB)中,直到该缓冲区被填满。此选项比TCP_NODELAY(即禁用Nagle算法)更强,因此即使设置了TCP_NODELAY选项,它仍将起作用。聚合到同一缓冲区的含义是,对于tcp_push()函数(net/include/tcp.c)的调用不会导致对__tcp_push_pending_frames()函数(net/include/tcp_output.c)的调用,后者最终会调用NIC的驱动程序xmit函数。相反,来自应用程序的下一条消息的有效负载将被复制到与上一条消息相同的缓冲区中。有关消息处理,请参见tcp_sendmsg()函数(net/include/tcp.c)。
另一方面,tcp_autocorking不会强制在缓冲区填满之前进行聚合,而是检查是否继续在当前缓冲区中进行聚合的特定条件。tcp_push()函数调用tcp_should_autocork()函数(net/include/tcp.c)以检查当前缓冲区是否应该发送:
static bool tcp_should_autocork(struct sock *sk, struct sk_buff *skb,
int size_goal)
{
return skb->len < size_goal &&
sysctl_tcp_autocorking &&
skb != tcp_write_queue_head(sk) &&
refcount_read(&sk->sk_wmem_alloc) > skb->truesize;
}
如果(缓冲区未满)且(自动塞塞功能已启用)且(队列中至少有一个数据包或网卡队列中至少有一个数据包)且(队列和网卡队列中不是所有数据包都是ACK),则英文“should cork”。
tcp_push()函数会检查其他条件,即使tcp_should_autocork()返回“true”也可能会中止“corking”操作。
希望这可以帮到您。