计网这门课里,要论“看着简单却容易丢分”的东西,计算题一定排得上号。平时上课听概念都懂,一到考试把链路层、网络层、传输层的大题放在一起,很多人就懵了。这份整理是我计科-计网系列的第8篇,专门把计网里最常考的那几类计算题捞出来,从CRC校验、最小帧长,到子网划分、IP分片,再到滑动窗口效率和TCP拥塞控制,套路和手算过程都会过一遍。期末突击、考研复习、自考刷题,都可以直接拿过去用。
1. 计网计算题到底在考什么
1.1 为什么计网计算题总丢分
我见过太多同学在计网计算题上翻车,但说实话,这类题目的难度并不高,原因是它不像高数那样绕,反而更像“协议流程 + 单位换算”的组合题。丢分往往丢在三个地方:第一,知识点太散,每一层都有属于自己的一两个计算题,你学到后面忘了前面;第二,单位混乱,带宽用Mbps、帧长用字节、传播速率用m/s,混在一起不统一,结果差好几个数量级;第三,流程性题目不会动态推演,比如TCP拥塞控制,算法本身两条规则就讲完了,难的是“第几个RTT超时”“阈值以谁为基准”“重传后cwnd到底从几开始”。
我的建议是:拿到一个计算题,先判断它考的是哪一层。CRC和最小帧长属于链路层,子网划分和IP分片属于网络层,滑动窗口和拥塞控制属于传输层。判断完层级,你脑子里就有对应的公式和操作流程,而不是看到数字就硬套。把“在做什么”搞清楚,计算题才不会成为玄学。
还有一个很常见的现象:不少同学公式背得滚瓜烂熟,但不会用。比如最小帧长公式里的τ到底取单程还是往返,停止等待协议的信道利用率分母到底是发时延加单程还是加往返,这些细节一含糊,结果就全错了。所以我不建议纯背公式,而是每道题都先问自己一句:这个公式的分子分母分别代表什么时间?这样不管题目怎么换皮,你都能反应过来。
1.2 高频考点一览
计网计算题虽然分布在各层,但期末和考研真正反复出现的,翻来覆去就是下面这些:
| 考点 | 常考形式 | 核心公式 / 关键点 |
|---|---|---|
| CRC循环冗余校验 | 给信息位和生成多项式,求发送序列 | 模2除法,余数位数等于最高次数,发送序列=信息位+余数 |
| CSMA/CD最小帧长 | 给距离、传播速率、数据率,求最短帧长 | 最短帧长 ≥ 2τ×R,τ是单程传播时延 |
| 子网划分 | 给IP和子网数,求掩码、主机数、合法范围 | 借k位满足2^k≥子网数,主机数=2^(32-新掩码)-2 |
| CIDR路由聚合 | 多个子网合并成一个 | 转二进制,找最长公共前缀 |
| IP分片 | 给总长度和MTU,求分片数、片偏移、MF | 每片数据部分(除最后一片)必须是8字节整数倍 |
| 停止等待/滑动窗口效率 | 给帧长、带宽、RTT,求信道利用率 | 发送时延/(发送时延+RTT),可乘窗口数但不超过1 |
| TCP拥塞控制 | 给ssthresh和RTT,推cwnd变化过程 | 慢启动×2,拥塞避免+1,超时ssthresh=cwnd/2、cwnd=1 |
这七类基本就是计算题的“全部弹药”。把这表看明白,后面就是熟练度问题。下面我会按链路层、网络层、传输层的顺序,把每类题的完整手算流程拆开讲。
2. 链路层必考:CRC校验与最小帧长计算
2.1 CRC手算完整流程
CRC循环冗余校验在数据链路层做检错,本质是模2除法。所谓模2除法,和普通除法最大的区别是每一位都是按位异或,没有进位也没有借位。生成多项式写成二进制时只看系数,比如 G(x)=x^3+x+1,从高次项到低次项系数分别是1、0、1、1,所以除数就是1011。这里的最高次数r=3,意味着要在信息位后面补3个0,再拿补完的序列去除以多项式对应的二进制数。
举个例子:信息位M=1011001,生成多项式G(x)=x^3+x+1。先写出被除数:M后面补3个0,得到1011001000。然后用1011逐步做异或除法,最终余数是011。发送方发出的完整帧就是“信息位 + 余数”,也就是 1011001 011。接收方拿到整个帧后,用同一个1011去除,余数为0就认为没有出错。注意余数是3位,如果算出来只有2位,前面必须补0凑满r位,这一点特别容易丢分。
做这道题最容易翻车的有三处:一是多项式写成二进制时漏常数项,比如x^3+x+1写成1010,后面计算全错;二是余数前置0被省略,导致发送序列长度不对;三是把“信息位+余数”的顺序写反。CRC在硬件里是用移位寄存器实现的,考试只要求手算,但原理一样,你可以把它理解成一条固定规则的位操作流水线,按位往下扫,最后剩下r位余数。每次做题都把异或过程写清楚,宁可写慢一点,也别凭感觉跳步。
2.2 以太网最小帧长与冲突检测
CSMA/CD的计算题几乎只考一个点:最短帧长。要理解它,必须先理解冲突检测窗口。以太网是边发边听的,站点在发送过程中同时检测总线上是否有冲突。信号从总线一端传到另一端需要单程传播时延τ,如果刚好在帧快要发完的时候出现冲突,发送端可能已经发完了,冲突信号回来时它已经处于不监听状态,就会漏判。所以规定:一个帧的发送时间必须大于等于2τ,也就是冲突信号一来一回的时间,这就是“争用期”。于是最短帧长=数据发送速率×争用期=速率×2τ。
题目一般这么出:某以太网连接长度1km,电磁波在介质中的传播速度为2×10^8 m/s,数据率为100Mbps,求最小帧长。先算单程传播时延:τ=1000/(2×10^8)=5×10^-6 s。再算争用期:2τ=10^-5 s。最后最小帧长=10^-5×100×10^6=1000bit,也就是125字节。如果算出来不是整数,要向上取整到字节,因为帧长必须按字节发送。
这里有几个坑要提醒。公式里的“带宽”是数据发送速率,不是信道带宽,题目给“100Mbps”就直接用这个数。另外τ是单程传播时延,如果题目直接给RTT(往返时延),那就不需要再乘2,因为2τ就是RTT。很多同学背了“最短帧长=2τ×速率”,看到RTT又下意识再乘2,结果多了一倍。考试还会反过来问“最远能传多远”,那就用标准帧长反推允许的2τ,再除以传播速率,注意要除以2才是距离。
2.3 实操心得:单位换算与常数别死记
链路层这两题,我真的建议你把所有单位统一成“bit”和“秒”再算。长度用米,时间用秒,速率用bit/s,帧长用bit。题目给字节就先乘以8,给km就先化成米,给Mbps就写成×10^6。我曾经见过一个学弟把1km直接代入公式,忘了化成1000m,结果算出来的最小帧长只有0.125字节,整个题毁在第一步单位换算上。
还有一个小经验:常数别死记。考试时如果忘了电磁波在介质中的传播速度,可以大致认为等于2×10^8 m/s,约是光速的三分之二;但更稳妥的是认真看题,因为题目几乎都会给。至于标准以太网最小帧长64字节,那是规定值,不是推导出来的“唯一答案”,做题时不要把64字节这一条当成公式。链路层的计算题是计网里最“良心”的题,公式短、变量少,只要你单位换算过关,基本就是送分题。
3. IP网络层计算:子网、聚合与分片
3.1 子网划分三步走
子网划分是网络层最经典的计算题,套路非常固定。第一步,看原来的掩码和需要的子网数,确定借用几位主机位。比如192.168.10.0/24是一个C类地址,要划分成4个子网。因为2^2=4,所以从主机位借2位,新掩码从/24变成/26。第二步,算每个子网的地址块大小:2^(32-26)=64,也就是说每个子网有64个IP地址。第三步,从0开始按块大小递推,写出每个子网的网络地址和合法主机范围。
具体到这个例子,四个子网分别是192.168.10.0/26、192.168.10.64/26、192.168.10.128/26、192.168.10.192/26。合法主机范围分别是1~62、65~126、129~190、193~254。每个子网的广播地址就是下一个子网网络地址减1,比如第一个子网广播地址是192.168.10.63。为什么主机数要减2?因为网络地址和广播地址不能分配给主机用,它们是固定的,一个是“本子网”,一个是“全体广播”。
做这类题最纠结的是“全0和全1子网到底能不能用”。CIDR出现以后,全0子网和全1子网默认可用,所以子网数就是2^k;但如果题目明确说“按老教材”“不允许全0/全1子网”,那可用子网数是2^k-2。我给你的建议是审题,以题目倾向为准,不要在考场上自作主张。还有一个易错点:题目问“每个子网能容纳多少台主机”,答案不是64,而是62,别在最后一步忘了减2。
3.2 路由聚合:找最长公共前缀
路由聚合和子网划分是互逆操作。子网划分是把一个大块切成小块,路由聚合是把小块合并成大块。计算的核心方法是:把IP地址的对应字节转成二进制,从最高位往低位数,看前面多少位完全一致,一致的位数就是聚合后的掩码长度。
举个例子:10.1.0.0/24、10.1.1.0/24、10.1.2.0/24、10.1.3.0/24这四个子网要聚合。前两个字节10和1完全一样,不用管,关键看第三字节:0是00000000,1是00000001,2是00000010,3是00000011。这四个数前6位都是000000,只有最后2位在变,所以公共前缀是原来的16位+6位=22位,聚合结果就是10.1.0.0/22。这个聚合后的地址块包含2^(32-22)=1024个IP地址,刚好是4个/24的总和,用这个反推可以验证是否算错。
这里必须强调一个前提:聚合不是“看到几个子网就拼在一起”。必须满足两个条件:子网地址块连续,而且数量是2的幂。比如10.1.0.0/24和10.1.2.0/24中间缺了10.1.1.0/24,就不能直接合并成10.1.0.0/22,因为聚合出来的地址块会包含不存在的子网。做题时别盯着十进制差异看,一定要转二进制找公共前缀,这才是路由聚合的本质。
3.3 IP分片计算:三个容易错的地方
IP分片是网络层计算题里最容易绕晕的一道,因为它涉及总长度、片偏移、MF、DF四个字段,而且片偏移单位非常反直觉。你需要死记三点:第一,总长度和MTU都以字节为单位,但片偏移字段以8字节为一个单位;第二,除了最后一个分片,每个分片的数据部分长度必须是8的整数倍,这样才能用整数表示偏移;第三,每一片都要单独加20字节IP首部,所以分片后的“总长度”不是简单把原始数据切割。
看一个经典题:原始IP数据报总长度4000字节,其中包含20字节首部,要经过MTU=1500字节的链路,问分成几片、每片的长度和片偏移。原始数据部分=4000-20=3980字节。每片最大总长度是1500,所以每片数据最多1500-20=1480字节,而1480÷8=185,正好是8的整数倍。于是分3片:片1数据1480,总长度1500,片偏移0,MF置1;片2数据1480,总长度1500,片偏移185,MF置1;片3数据1020,总长度1040,片偏移370,MF置0。片偏移370是怎么来的?前两片数据共2960字节,2960÷8=370。
这个题有三个隐藏考点。第一,如果MTU给的是2000字节,最大数据部分理论上是1980字节,但1980不是8的整数倍,需要向下取整到1976。这是考试常挖的坑,看到不能整除不要直接往下算,先调整。第二,MF字段表示“后面还有分片”,除最后一片外都必须置1;DF字段表示“是否允许分片”,DF=1时这个数据报不能分片,如果超过MTU就直接丢弃。第三,接收方重组时把片偏移×8就能得到该片数据在原报文中的起始位置,所以片偏移是一个相对量,不是绝对长度。
4. 传输层效率:停止等待协议与滑动窗口计算
4.1 信道利用率到底怎么算
传输层计算题集中在可靠传输机制,停止等待协议的信道利用率是最常见的开场题。要理解公式,先理解“一个完整的发送周期”。发送端发出一个帧,要先花一段时间把帧推上线,这叫发送时延;之后信号在链路上飞行,到达接收端;接收端处理并返回确认;确认再飞回发送端。从发送端角度看,这个周期除了发送时延之外,剩下的都是“等确认”的时间。所以停止等待协议的信道利用率=发送时延/(发送时延+RTT)。如果题目给的是单程传播时延τ,那RTT就写2τ,公式变成发送时延/(发送时延+2τ)。
举个例子:数据帧长1000bit,链路速率1Mbps,RTT=10ms。发送时延=1000/10^6=1ms,利用率=1/(1+10)=9.1%。这个数字很直观地说明了停止等待的缺点:信道大部分时间空着,效率很低。确认帧的发送时延通常忽略,但如果题目专门给了确认帧长度,那分母就要加上确认发送时延。“周期里到底有几段时间”是核心,想明白这个,公式不用背。
滑动窗口协议的利用率,等于在一个周期内实际能连续发送多个帧的时间占总周期的比例。如果发送窗口大小为N,利用率可以写成 N×发送时延/(发送时延+RTT)。但这个值有个上限:不能超过100%。当N大到能把整个周期填满时,再增加窗口也不会让单条连接跑得更快,因为物理带宽已经封顶了。做题时记得加一个取min的判断,别算出150%还往上写。
4.2 发送窗口大小的限制:接收窗口和带宽时延积
滑动窗口协议里有一道高频题:在高速长距离链路上,发送窗口至少多大才能让信道利用率接近100%?这里用到的概念是“带宽时延积”。所谓带宽时延积,就是链路上同时能容纳的比特数,等于带宽×RTT。它描述的是“这根管道里最多能塞多少数据”。如果你把链路想成一根水管,带宽是水龙头流速,RTT是水从这头流到那头再回来的时间,带宽时延积就是这一刻正泡在水管里的水量。
比如链路速率1Gbps,RTT=20ms,帧长1000字节。带宽时延积=1×10^9×0.02=2×10^7bit,帧长=1000×8=8000bit,那么需要的发送窗口至少是2×10^7/8000=2500帧。如果考序号位数:GBN协议最大发送窗口是2^n-1,满足2^n-1≥2500的最小n是12;像SR这种选择重传协议,最大发送窗口是2^(n-1),满足条件的最小n是13。差异来自协议窗口上限的不同,别混。
这类题真正想考的是“为什么滑块窗口不能无限大”。序号空间是有限的,如果发送窗口太大,新旧序号就会重叠,接收方分不清收到的到底是新包还是重传的旧包。因此窗口大小受两个约束:一是接收窗口的流量控制,二是序号空间的协议限制。做题时把这两个约束都列出来,答案就完整了。
4.3 一个完整例题:停止等待的“死等”与流水线对比
把上面公式串起来看一个完整例子。假设数据帧长2000字节,链路速率10Mbps,RTT=4ms。发送时延=2000×8/(10×10^6)=1.6ms。停止等待协议下,一个周期=发送时延+RTT=1.6+4=5.6ms,信道利用率=1.6/5.6≈28.6%。如果改用滑动窗口且窗口N=3,利用率=3×1.6/5.6≈85.7%。当N=4时,4×1.6/5.6≈114%,但实际上限是100%,所以取N=4就刚好填满周期。
为什么N=4就够了?因为4个帧连续发送需要4×1.6=6.4ms,比一个周期5.6ms更长,发送端在这个周期里不会再出现空等。如果窗口继续增大,超出接收窗口限制会被卡住,超出序号空间限制会乱套,而单条连接的利用率已经到顶。所以考试里如果问“最小窗口是多少”,就解 N×发送时延 ≥ 发送时延+RTT,取最小整数;不要无脑觉得窗口越大越好。停止等待和滑动窗口对比着看,你会发现所有公式都在描述同一件事:一个周期里,信道到底有多少时间在真的传数据。
5. 拥塞控制计算:慢启动、阈值与超时后的变化
5.1 三个参数的“剧情”怎么发展
TCP拥塞控制计算题,公式很少,考的是“剧情”推演。你必须记牢几条规则:慢启动阶段,每经过一个RTT,拥塞窗口cwnd翻倍;当cwnd达到或超过慢开始门限ssthresh时,进入拥塞避免阶段,之后每经过一个RTT,cwnd只加1个MSS。如果发生超时,ssthresh变成当前cwnd的一半,同时cwnd归1,重新走慢启动。如果收到3个重复ACK触发快速重传,ssthresh也变成当前cwnd的一半,但cwnd不是归1,而是变成ssthresh+3×MSS,然后进入快速恢复阶段。
最大的坑在“当前cwnd”这四个字。阈值减半,减的是超时那一刻已经增长出来的cwnd,不是最开始的ssthresh。比如初始ssthresh=16,cwnd涨到17时超时,那ssthresh=⌊17/2⌋=8,cwnd=1。很多人顺手写16/2=8,只是碰巧结果一样,换个数就会错。所以做这类题,我要求自己每一步都先写上“当前cwnd、当前ssthresh”,再继续推下一个RTT。把变量标清楚,流程就不会乱。
还有一个要注意的地方:拥塞控制和流量控制是两回事。拥塞控制是发送端根据网络状态调整cwnd,流量控制是接收端根据自身处理能力告诉对方接收窗口。实际发送窗口=min(cwnd, 接收窗口)。题目如果同时给接收窗口,一定要把这个min加上,否则算出来的窗口可能超过接收方许可,显然是错的。
5.2 例题:从1MSS开始画时间轴
设初始ssthresh=16MSS,cwnd从1MSS开始增长,这里的“轮”按一个RTT计算。慢启动阶段:第1轮结束cwnd=2,第2轮结束=4,第3轮结束=8,第4轮结束=16。到达阈值后,第5轮进入拥塞避免,cwnd从16变成17。所以如果题目问“第几个RTT后进入拥塞避免”,答案是第5个RTT。从第5轮开始,cwnd不再是翻倍式增长,而是每个RTT只加1。
假设第5轮结束、cwnd=17时发生超时。于是ssthresh=17/2向下取整=8,cwnd=1。之后重新慢启动:第1轮结束=2,第2轮结束=4,第3轮结束=8,此时cwnd重新碰到ssthresh,第4轮进入拥塞避免,cwnd=9。如果题目在第6轮又来一次3个重复ACK,那又要按快速重传处理:ssthresh=8/2=4,cwnd=4+3=7,之后每轮加1。这种题只要画一个时间轴,横轴写RTT编号,纵轴写cwnd数值,再把ssthresh线画出来,基本不会错。
画时间轴时有一个细节要留意:题目说“在第几轮发生超时”,可能指发送阶段中途超时,也可能指这一轮结束后才发现。这两种说法会影响cwnd的取值时点。我考场上比较笨但很稳的做法是,在图上标出每一个“事件发生点”,然后问自己:这个节点的cwnd是事件前还是事件后的值?按这个顺序写步骤,即使最终数字出了小差错,老师也能看到你的流程是对的。
5.3 常见坑:阈值、重复ACK、拥塞窗口单位
总结一下拥塞控制题的常见错误,几乎可以列成一张避坑清单。第一,单位混淆。题目说MSS=1000字节,cwnd=8MSS,问发送窗口是否受接收窗口限制时,要把8MSS换算成8000字节再和接收窗口比较。第二,快速重传的“+3”不是随便加的,它代表已经收到3个重复ACK,说明接收端缓存里有3个报文段等待排序,发送窗口要放这部分空间。第三,ssthresh减半后如果小于2,有些教材规定最小为2,防止窗口太小完全卡死。第四,超时和快速重传不要混在一起,超时后cwnd=1,快速重传后cwnd≠1,两个是完全不同的剧本。
我自己的做题流程是:先用中文写一遍剧情——“慢启动到第几轮、碰到阈值、进入拥塞避免、发生超时、阈值减半、重新慢启动”,然后才动笔填数字。这个过程相当于先替自己整理逻辑,把错误在草稿阶段就拦下来。TCP拥塞控制是所有计网计算题里最像“时间轴游戏”的题目,只要把握了每个事件发生时cwnd和ssthresh的取值,满分不难。
6. 综合题实战:从读题到写答案的完整流程
6.1 设计一道“一条龙”综合题
把前面几个考点串成综合题,最能看出你掌握得扎不扎实。我常拿下面这题给学弟练手:主机A向B传文件,RTT=40ms,TCP初始ssthresh=8MSS,MSS=1000字节,接收窗口为10000字节。第一问,慢启动阶段几个RTT后进入拥塞避免?cwnd从1开始,第1轮结束=2,第2轮结束=4,第3轮结束=8,等于阈值,所以第4轮进入拥塞避免,cwnd变为9。第二问,若此时发生超时,ssthresh和cwnd分别变为多少?ssthresh=4,cwnd=1。第三问,之后第2轮结束时cwnd是多少?从cwnd=1重新慢启动:第1轮结束=2,第2轮结束=4,第三轮才会进入拥塞避免变5,所以答案是第2轮结束为4。
这道题里有好几个“隐藏数字”要注意。接收窗口10000字节=10MSS,当接收窗口限制存在时,实际发送窗口不能超过10MSS,所以无论拥塞窗口怎么增长,cwnd到10就封顶了。很多同学忽略这一点,算出超过10的值还不知道错在哪。回答综合题时,先把已知量列出来:RTT=40ms、ssthresh=8MSS、接收窗口=10MSS、MSS=1000字节。然后每个小问都单独写公式和当前状态,即使某一步错了,步骤分也能保住一大半。
6.2 考场答题顺序与公式速查
考场上做计网计算题,我建议按这个顺序走。第一步,用笔圈出题目所有数值和单位,顺手统一成bit、s、字节;第二步,判断题型所属层级,链路层、网络层还是传输层;第三步,先写公式再代数字,单位不要省;第四步,流程推演题先画RTT时间轴,再填数字。这个流程听起来简单,但能避免大部分低级失误。
下面这张速查表是我自己考前默写的版本,可以抄走:
- 发送时延 = 帧长 ÷ 发送速率
- 传播时延 = 距离 ÷ 传播速率
- RTT = 2 × 单程传播时延(如果直接给RTT,不要再多乘2)
- 最小帧长 ≥ 2τ × 速率
- 子网可用主机数 = 2^(32-掩码位数) - 2
- 片偏移 = 该片数据首字节编号 ÷ 8
- 停止等待信道利用率 = 发送时延 ÷ (发送时延 + RTT)
- 滑动窗口信道利用率 = min(N×发送时延 ÷ (发送时延+RTT), 1)
- 慢启动:cwnd每RTT × 2
- 拥塞避免:cwnd每RTT + 1
- TCP超时:ssthresh = cwnd/2,cwnd = 1
- 快速重传:ssthresh = cwnd/2,cwnd = ssthresh + 3×MSS
这些公式不需要考前临时背,建议平时做题时反复默写,做到闭着眼都能写出来。考场上一旦卡壳,就回到“这个公式的分子、分母分别代表什么”这个原点,一般都能想起来。
6.3 复盘:我当年刷计算题踩过的坑
整理这套笔记的时候,我正在给准备期末的学弟答疑,发现自己当年也犯过一样的错误:拿到题习惯性先找公式套数字,完全不看题型背景,结果CRC把多项式写成十进制的值,子网划分忘了减2,IP分片把片偏移单位当成字节,拥塞控制里超时和快速重传分不清。踩过几次坑之后,我改成了“先讲流程,再动笔”的习惯。
每道计算题我都会问自己一句:这个数字背后,协议到底在做什么?CRC在算余数,子网划分在借主机位,分片在切数据段,滑动窗口在决定同时发多少个帧,拥塞控制在根据网络状态调整发送量。公式只是把这些动作量化,理解了动作,公式就变成了“顺理成章”而不是“死记硬背”。这份整理是计算题专题,后面如果再遇到让你头疼的计网题型,我还是建议用这个思路去拆:先想清楚协议流程,再统一单位,最后写公式。计网计算题不是数学考试,是“协议流程+单位换算”的组合拳,把流程画顺,分数自然到手。