公众号旧文

下载时,你的电脑只是接收数据吗?

作者:胖子阅读 —

我以前对下载的理解,一直是这样的:

点击下载
服务器开始发文件
我的电脑只负责接收
一直到下载完毕

于是会下意识觉得下载是单向的。

但刚刚真正抓了一次 TCP 包,才知道事情根本不是这样。

实际上在下载文件的整个过程中,电脑也一直在向服务器发送数据。

而且没有这些数据,下载甚至根本无法进行。

一、用户的直觉

从用户视角来看,下载时:

  • 接收速度远大于发送速度
  • 磁盘上的文件越来越大
  • 下载进度条不断前进

于是我们会自然理解成,下载就是数据一直从服务器流向自己,就像水龙头往洗手池里面注水,偶尔零星的那些发送速度,可能是其他程序在上传些什么东西。

但互联网底层并不是这样工作的。

二、真正的 TCP 下载

服务器每发送一段数据:

这是下一段文件

你的电脑都会立刻回复:

收到
继续发

如果某段丢了:

刚才那段没收到
重发一下

如果网络太堵:

你先慢一点
我这边快满了

整个下载过程其实是:

服务器发
客户端确认
服务器继续发
客户端继续确认

不断循环。

三、这个确认,就是 TCP ACK

TCP 有一个非常核心的机制:ACK(Acknowledgement)

意思是:

我收到了

比如服务器发送:

1~32768 字节

你的电脑收到后,会返回:

ACK=32769

意思是:

前 32768 字节已经全部收到
请继续发送

所以下载并不是默默接收,而是一场高速的双向对话。

四、我亲自抓包后,才真正理解这件事

我在自己的服务器上搭了一个测速下载站。

然后使用:

tcpdump -i any port 18080

抓 TCP 包。

结果发现屏幕上疯狂出现:

服务器 DATA
客户端 ACK
服务器 DATA
客户端 ACK

不断循环。

例如:

length 65483

说明:

服务器正在发送数据

而:

ack 164074

说明:

客户端正在告诉服务器:
前 164073 字节已经收到了

这时候我才真正意识到下载时,客户端一直在说话。

五、为什么必须这样?

因为互联网本身并不可靠。

现实中的网络:

  • 会丢包
  • 会拥塞
  • 会乱序
  • 会延迟波动
  • 会中途断线

服务器根本不知道你到底收到了没有,所以客户端必须不断确认。

否则服务器只能瞎发,而这会导致:

  • 文件损坏
  • 数据丢失
  • 下载失败

六、这也是为什么上传跑满会影响下载

很多老网民都经历过:

我明明在下载
为什么上传占满后下载速度暴跌?

原因就是 ACK 发不出去。

服务器收不到你的确认:

“你是不是没收到?”

于是降速、等待、重传,下载速度立刻崩掉。

七、最反直觉的一点

很多人会觉得 ACK 不就是几个字节吗?

但互联网里,小小的 ACK,控制着整个下载过程。

它决定:

  • 是否继续发送
  • 发送多快
  • 是否重传
  • 是否断开
  • 是否拥塞

所以 TCP 的核心,就是反馈。

八、一句话总结

你下载文件时,并不是服务器单方面往你电脑里灌数据

而是服务器不断发送,客户端不断确认,双方持续协调传输状态。