• [tcp/ip] tcp delayed ack


    触发机制

    被delay的ack包,什么时候发送出来?

    1. 到达500ms (这个值根据实现的不同而不同,RFC要求最多不能超过500,linux的实现是200)
    2. 每两个数据包回一个ack
    3. 由反向数据包发送带回。

    优点

    delayed ack可以提供一个机会给应用程序。让三个回应报合并成一个回应包。

    三个分别为:ack,窗口更新,应用层回应。

    应用层回应显然是应用程序主动发回的。窗口更新也跟应用层有关,是因为应用程序从buffer里读走了数据,窗口自然会发生更新。

    所以,ack延迟500毫秒,最大的好处是为了让这三个信息从一个包里携带过去。

    缺点

    write write read 问题

    当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算法进行配置。

    • nagle: 选项 TCP_NODELAY 用来控制发包侧的行为。
    • delayed ack: 选项 TCP_QUICKACK 用来控制收包侧的行为。
      • 值得一提的是,delay ack与quick ack(快速确认)直接的转换是协议栈动态调节的,即使在同一条TCP连接里,显式设置的该选项

    也会被OS在恰当的时机里调节回去。

    参考:man 7 tcp

    参考

    https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment

  • 相关阅读:
    Ant Design Vue中TreeSelect详解
    ant-design-vue 表单验证详解
    vue3跟新视图遇见神奇现象
    遇见这样的数型结构图我是这样画的
    Ant Design Vue中Table的选中详解
    2021 年百度之星·程序设计大赛
    2021 年百度之星·程序设计大赛
    2021牛客暑期多校训练营7 H. xay loves count(枚举)
    2021牛客暑期多校训练营6 H. Hopping Rabbit(扫描线)
    P1494 [国家集训队]小Z的袜子(莫队)
  • 原文地址:https://www.cnblogs.com/hugetong/p/13208823.html
Copyright © 2020-2023  润新知