有些知识,平时看起来没什么用,等到真正排查一个慢到离奇的接口、抓一份看不懂的TCP报文、或者被面试官追问“为什么TCP是可靠的”时,才发现自己其实从来没真正搞懂过。流量控制与可靠传输,就是计算机网络里最容易被“背会”却最难被“理解”的一块。这篇文章不打算复述教科书,而是从为什么需要、怎么实现、实际报文怎么呈现、遇到问题怎么排查这几个角度,把滑动窗口、可靠传输、拥塞控制这些东西彻底聊透。不管你是正在准备期末、考研408,还是要转开发、测试岗,都能从里面找到真正能用的理解方式。
1. 可靠传输要解决的根本问题
1.1 为什么IP层“尽力而为”,TCP却非要“说到做到”
网络层只提供不可靠的交付,IP数据报在传输过程中可能丢失、重复、乱序,甚至被路由器悄悄丢弃。不要觉得这是设计缺陷,恰恰相反,这是网络层特意保持的“轻量”:路由器只管转发,不维护任何连接状态,这样才能保证整个互联网的扩展性。传输层的TCP则把“可靠交付”这件事承担下来,在不可靠的IP之上,用确认、重传、去重、排序等机制,向上层提供一个看起来完美有序的字节流。
这个分工值得停下来想一想:如果让网络层做可靠交付,每个路由器都要维护大量连接的状态,核心路由器的压力会大得不可想象。把可靠机制放在端系统上,路由器保持无状态转发,网络的规模才能扩展到今天这个程度。所以TCP的所有复杂度,本质上都是“在不可靠网络上模拟可靠信道”的代价。
1.2 三种可靠传输机制的演进逻辑
教科书里讲可靠传输,通常会从三个协议讲起:停止等待协议、后退N帧协议、选择重传协议。这三个协议不是并列的,而是同一个问题在不同约束下的三种解法。
停止等待协议的核心是“发一个,等确认,再发下一个”。发送方每发送一个分组就启动超时计时器,收到确认后发送下一个,超时则重传。这个机制的正确性很容易证明,但效率低得让人着急:在往返时延RTT为100ms、带宽为1Gbps的链路上,发送一个1KB的分组,信道利用率算下来只有0.008%。换句话说,99.99%的时间里信道是空的。
于是有了流水线思想:发送方不用等一个确认再发下一个,而是可以连续发送多个分组。后退N帧协议允许发送窗口大于1,接收方只按序接收,一旦发现乱序就丢弃后续分组,发送方要回退重传。选择重传协议更进一步,接收方把乱序到达的分组缓存下来,只需重传真正丢失的那一个。
从停等到后退N再到选择重传,本质上是一个“用接收方缓存换带宽效率”的过程。后退N帧需要的接收方缓存很少,但一旦出错就要重传很多分组;选择重传只重传丢失的那个,对带宽友好,但要求接收方有足够缓存放乱序到达的数据。实际TCP采用的选择确认机制SACK,就是选择重传思想在真实协议中的落地。
提示:理解这三种机制的演进,对面试和考试都很关键。面试官喜欢问“TCP可靠传输是怎么实现的”,你如果能从停等讲到选择重传,再落到TCP实际怎么做的,这段回答的层次感会比直接背答案好很多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 滑动窗口:流量控制与可靠传输的共同地基
2.1 发送窗口和接收窗口各自管什么
滑动窗口是TCP里最核心的结构,流量控制、可靠传输、拥塞控制全都围绕它运转。先明确一个容易混的点:TCP的滑动窗口分为发送窗口和接收窗口,两者各管各的。
发送窗口由发送方维护,表示“我当前可以连续发送的字节范围”。窗口左边界是“已发送且已确认”的字节,右边界是“还没发送但允许发送”的最远位置。窗口内的字节分三类:已发送等确认、已发送且确认、未发送但允许发送。窗口外的字节不允许发送。
接收窗口由接收方维护,表示“我当前还有多少缓冲区能接收数据”。接收方在TCP首部的窗口字段里告诉发送方自己的接收能力,发送方看到这个值后,把自己的发送窗口限制在“小于等于接收窗口”的范围内。这就是流量控制的本质:接收方的处理能力,通过窗口字段反向约束发送方的发送行为。
窗口的滑动规则也值得写清楚。发送方每收到
