关于 TCP delayed ACK 问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
iqoo

关于 TCP delayed ACK 问题

  •  
  •   iqoo Oct 11, 2022 2696 views
    This topic created in 1297 days ago, the information mentioned may be changed or developed.

    使用 HTTP 下载一个 20MB 的文件,抓包发现客户端应答了 2500 多个 ACK 包,总共 160KB 。

    如果绕过 TCP 协议栈(比如 libpcap )写一个 HTTP 下载程序,客户端隔较长时间答复 ACK ,最终只应答了 60 个 ACK 包,文件同样也能传输成功,而客户端只发送了几 KB 的流量。

    不知常用的系统(比如 Linux )是否可通过设置,把 ACK 应答数量减少到极致?看了下 TCP delayed ACK ,规定最大超时是 500ms ,并且收到的数据量足够时就得应答。貌似不好实现。

    有些场景下,机器出流量昂贵,但入流量免费且带宽充足,因此即使对方重传包也不影响费用,而我方产生 ACK 则是计费的,因此越少越好。

    Supplement 1    Oct 11, 2022
    如果我方 ACK 应答时机控制恰到好处,对方会认为带宽充足,没有丢包,每批次的包数也会增加。对方甚至会一次发几百个包,而我只需答复一个 ACK 包就行。几十字节即可换几百 KB 。
    17 replies    2022-10-12 14:15:43 +08:00
    sujin190
        1
    sujin190  
       Oct 11, 2022
    你都绕过 tcp 了,那就直接用 udp 呗,莫非你是想传输的还是 tcp 包,但是不发 ack ? tcp 是要求每个 ip 包都必须有 ack 的吧,因为丢包可能只是中间某个包丢了,前后都没问题,没收到 ack 的 ip 包就是丢包了需要重传,tcp 协议似乎并不能处理你说的这种可以跳 ack 的情况,所以如果你想要这样那你似乎要同时自己实现 client 和 server ,不过既然你都这样干了,直接用 raw socket 就行吧
    sujin190
        2
    sujin190  
       Oct 11, 2022
    TCP delayed ACK 好像说的是稍微延迟 ack ,然后把多个 ack 放在一个 ip 包里发送,用于减少 ip 包的数量,并没有说可以跳过中间的 ack 直接发送最后一个就行
    tool2d
        3
    tool2d  
       Oct 11, 2022
    可以写一个 ip filter 网卡驱动过滤层,用代码去识别多余的一些 ACK IP 包,给主动过滤掉。
    laozhoubuluo
        4
    laozhoubuluo  
       Oct 11, 2022
    设置估计是没啥戏,因为这个不是标准实现。
    要做的话估计只能改内核实现,理论来说可以做到收到重传时才回复 ACK ,这样是最省入流量的。
    iqoo
        5
    iqoo  
    OP
       Oct 11, 2022
    @laozhoubuluo 其实也不一定。重传再应答,之后对方可能会降低窗口。本来对方一次发 20 个包停止,等我的 ack ,现在可能一次只发 10 个包,就在等我的 ack 。最理想的情况是踩着对方的窗口应答,当然需提前知道对方窗口相关的参数。
    newmlp
        6
    newmlp  
       Oct 11, 2022
    老老实实换 udp 吧
    iqoo
        7
    iqoo  
    OP
       Oct 11, 2022
    @sujin190
    @newmlp 目标服务就是 HTTP ,不可控
    jedihy
        8
    jedihy  
       Oct 11, 2022   1
    LS 有人说过了,写一个 filter driver 丢弃一些 ACK 是可行的,或者合并一些累计确认也是可以的。

    除非你的出口流量真的贵,不然的话有一些缺点:
    1. 会造成发送方流量突发。因为每个 ACK 能够"clock"的数据量变大了。
    2. ACK return 路径上的丢包会更容易导致发送发重传( RTO/TLP )进而降速。
    3. 某一些 TCPIP 实现,每个 ACK 能够增加的 cwnd 有限制。如 Windows 的 TCP ,每个 ACK 只能增加 8MSS 的 cwnd 。过少的 ACK 会导致慢启动阶段非常慢。
    zhs227
        9
    zhs227  
       Oct 11, 2022
    TCP 如果没有足够的 ACK 会窗口打不开,如果有丢包的话没办法快速的收敛到新的带宽大小上,有很多问题, 只适用于极有限的场景。不过单向数据发送这种场景,另一侧的 Ack 是冗余量较大的,之前试过反向丢掉 70%都没太大影响。
    iqoo
        10
    iqoo  
    OP
       Oct 11, 2022
    @zhs227 下载速度不敏感的场景可以尝试,比如后台的文件下载任务。如果连接数多,总吞吐反而更高。
    wangritian
        11
    wangritian  
       Oct 11, 2022
    查了些文章,据说 centos 可以通过 echo 500 > /proc/sys/net/ipv4/tcpdelackmin 设置 ack 的定时器间隔
    如果收到多个数据包会强制触发 ack ,不知道在交换机上对入网数据包拼装成巨型帧能否解决?
    lysS
        12
    lysS  
       Oct 11, 2022
    ack 的频率越高,流控、拥塞避免越接近算法的理论表现。tcp 在低速情况下每收到一个包都回复 ack ,在稳定的高速情况下,可能收到几个数据包才回复一个 ack ,我测得的最大值是 3 。

    其实那点流量不算什么,主要是频繁调用的 net io 导致 cpu“浪费”比较严重
    cubecube
        13
    cubecube  
       Oct 11, 2022
    @sujin190 你理解得不对,就是跳过。对端只关心你 ack 的序号。tcpdump 看看就明白了
    ntdll
        14
    ntdll  
       Oct 11, 2022
    优化方向是不是值得重新考虑,如果这点流量都需要算计出来,那 HTTP 头的浪费可远比这些大多了。
    sujin190
        15
    sujin190  
       Oct 11, 2022
    @cubecube #13 好吧,记错了,seq 是数据流的 offset ,那确实可以合并跳过
    iqoo
        16
    iqoo  
    OP
       Oct 11, 2022
    @gam2046 HTTP 头不过 100 字节,ACK 都有 160KB 了( 20MB 的文件)
    Defined
        17
    Defined  
       Oct 12, 2022
    打 ko 改协议栈?一直不回 ack 的话 client 端的窗口很容易就满了
    About     Help     Advertise     Blog     API     FAQ     Solana     5273 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 62ms UTC 07:57 PVG 15:57 LAX 00:57 JFK 03:57
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86