公众号旧文
下载时,你的电脑只是接收数据吗?
我以前对下载的理解,一直是这样的:
点击下载
服务器开始发文件
我的电脑只负责接收
一直到下载完毕
于是会下意识觉得下载是单向的。
但刚刚真正抓了一次 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 的核心,就是反馈。
八、一句话总结
你下载文件时,并不是服务器单方面往你电脑里灌数据
而是服务器不断发送,客户端不断确认,双方持续协调传输状态。