被delay的ack包,什么时候发送出来?
delayed ack可以提供一个机会给应用程序。让三个回应报合并成一个回应包。
三个分别为:ack,窗口更新,应用层回应。
应用层回应显然是应用程序主动发回的。窗口更新也跟应用层有关,是因为应用程序从buffer里读走了数据,窗口自然会发生更新。
所以,ack延迟500毫秒,最大的好处是为了让这三个信息从一个包里携带过去。
当delayed ack和nagle算法同时使用时,会引起write write read问题。 这个问题的本质是,传输层因为启用了这两个算法,而导致了应用层在等待传输层的问题。
举例:A与B通信,a发送1和2然后读取,b收到1和2后发送他们的和3给a,a最终收到1和2的和3.
这个场景的前提是1已经发出去了。然后a发送2并堵塞读。由于2已经交付给了操作系统。所以应用程序a便阻塞在了读操作上面。
这个时候,应1的ack还没有回来。所以a所在的操作系统因为nagle算法并不会把2发出去。
b所在的操作系统收到了1并交付给了应用程序b。但是b还没有收到加法的第二个操作数2,所以也不会主动发送他们的和3.
这个是a和b所在的两个tcp协议栈就在相互等待对方,而导致原本可应该更快处理的两个应用层程序出现了堵塞。a在等待1的ack,b在等待第二个操作数2。
这个僵局直到,b的delay ack到达500毫秒的超时发送了1的ack才会被打破。
这就是 write write read问题。
TCP慢启动是为了以指数增长的趋势快速逼近最大带宽。很显然,在这个前提下,delayed ack会使逼近速度降低。
所以在慢启动过程中,快速确认(quick ack)也是被启动的。linux里有这样一个宏定义的值,来达到这个目的
/* Maximal number of ACKs sent quickly to accelerate slow-start. */ #define TCP_MAX_QUICKACKS 16U
linux下,使用setsockopt()可以对这两个特性,delayed ack和nagle算法进行配置。
也会被OS在恰当的时机里调节回去。
参考:man 7 tcp
https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment
原文:https://www.cnblogs.com/hugetong/p/13208823.html