使用 HTTP 下载一个 20MB 的文件,抓包发现客户端应答了 2500 多个 ACK 包,总共 160KB 。
如果绕过 TCP 协议栈(比如 libpcap )写一个 HTTP 下载程序,客户端隔较长时间答复 ACK ,最终只应答了 60 个 ACK 包,文件同样也能传输成功,而客户端只发送了几 KB 的流量。
不知常用的系统(比如 Linux )是否可通过设置,把 ACK 应答数量减少到极致?看了下 TCP delayed ACK ,规定最大超时是 500ms ,并且收到的数据量足够时就得应答。貌似不好实现。
有些场景下,机器出流量昂贵,但入流量免费且带宽充足,因此即使对方重传包也不影响费用,而我方产生 ACK 则是计费的,因此越少越好。
1
sujin190 2022-10-11 11:55:37 +08:00
你都绕过 tcp 了,那就直接用 udp 呗,莫非你是想传输的还是 tcp 包,但是不发 ack ? tcp 是要求每个 ip 包都必须有 ack 的吧,因为丢包可能只是中间某个包丢了,前后都没问题,没收到 ack 的 ip 包就是丢包了需要重传,tcp 协议似乎并不能处理你说的这种可以跳 ack 的情况,所以如果你想要这样那你似乎要同时自己实现 client 和 server ,不过既然你都这样干了,直接用 raw socket 就行吧
|
2
sujin190 2022-10-11 11:58:20 +08:00
TCP delayed ACK 好像说的是稍微延迟 ack ,然后把多个 ack 放在一个 ip 包里发送,用于减少 ip 包的数量,并没有说可以跳过中间的 ack 直接发送最后一个就行
|
3
tool2d 2022-10-11 12:02:20 +08:00
可以写一个 ip filter 网卡驱动过滤层,用代码去识别多余的一些 ACK IP 包,给主动过滤掉。
|
4
laozhoubuluo 2022-10-11 12:08:14 +08:00
设置估计是没啥戏,因为这个不是标准实现。
要做的话估计只能改内核实现,理论来说可以做到收到重传时才回复 ACK ,这样是最省入流量的。 |
5
iqoo OP @laozhoubuluo 其实也不一定。重传再应答,之后对方可能会降低窗口。本来对方一次发 20 个包停止,等我的 ack ,现在可能一次只发 10 个包,就在等我的 ack 。最理想的情况是踩着对方的窗口应答,当然需提前知道对方窗口相关的参数。
|
6
newmlp 2022-10-11 13:37:24 +08:00
老老实实换 udp 吧
|
8
jedihy 2022-10-11 13:44:15 +08:00 1
LS 有人说过了,写一个 filter driver 丢弃一些 ACK 是可行的,或者合并一些累计确认也是可以的。
除非你的出口流量真的贵,不然的话有一些缺点: 1. 会造成发送方流量突发。因为每个 ACK 能够"clock"的数据量变大了。 2. ACK return 路径上的丢包会更容易导致发送发重传( RTO/TLP )进而降速。 3. 某一些 TCPIP 实现,每个 ACK 能够增加的 cwnd 有限制。如 Windows 的 TCP ,每个 ACK 只能增加 8MSS 的 cwnd 。过少的 ACK 会导致慢启动阶段非常慢。 |
9
zhs227 2022-10-11 14:19:48 +08:00
TCP 如果没有足够的 ACK 会窗口打不开,如果有丢包的话没办法快速的收敛到新的带宽大小上,有很多问题, 只适用于极有限的场景。不过单向数据发送这种场景,另一侧的 Ack 是冗余量较大的,之前试过反向丢掉 70%都没太大影响。
|
11
wangritian 2022-10-11 15:50:30 +08:00
查了些文章,据说 centos 可以通过 echo 500 > /proc/sys/net/ipv4/tcpdelackmin 设置 ack 的定时器间隔
如果收到多个数据包会强制触发 ack ,不知道在交换机上对入网数据包拼装成巨型帧能否解决? |
12
lysS 2022-10-11 16:00:25 +08:00
ack 的频率越高,流控、拥塞避免越接近算法的理论表现。tcp 在低速情况下每收到一个包都回复 ack ,在稳定的高速情况下,可能收到几个数据包才回复一个 ack ,我测得的最大值是 3 。
其实那点流量不算什么,主要是频繁调用的 net io 导致 cpu“浪费”比较严重 |
14
gam2046 2022-10-11 17:18:42 +08:00
优化方向是不是值得重新考虑,如果这点流量都需要算计出来,那 HTTP 头的浪费可远比这些大多了。
|
17
Defined 2022-10-12 14:15:43 +08:00
打 ko 改协议栈?一直不回 ack 的话 client 端的窗口很容易就满了
|