Appearance
题目
主机甲和主机乙之间已建立了一个 TCP 连接,TCP 最大段长度为 1000 字节。若主机甲的当前拥塞窗口为 4000 字节,在主机甲向主机乙连续发送两个最大段后,成功收到主机乙发送的第一个段的确认段,确认段中通告的接收窗口大小为 2000 字节,则此时主机甲还可以向主机乙发送的最大字节数是( )。
错因
B
直接给出 rwnd 值 2000——但 rwnd 是发送窗口的上限,不等于"还可以发的字节数"。已发未确认的字节占了一部分窗口,剩余 = 窗口 − 已发未确认 = 2000 − 1000 = 1000。错的根源:把"窗口大小"和"剩余可发空间"混淆。
C
可能算成"4000 cwnd − 1000 已发未确认 = 3000",忽略了 rwnd 的限制。发送窗口 = (cwnd, rwnd) = (4000, 2000) = 2000,不是 4000。错的根源:漏掉 rwnd 限制。
D
把 cwnd 4000 当成发送窗口——同 C 一样漏掉 rwnd 限制 + 漏减已发未确认。错的根源:完全没用 (cwnd, rwnd) 公式。
总解析
第一步:分析当前发送窗口
发送窗口 = (cwnd, rwnd) = (4000, 2000) = 2000 字节
接收方通告 rwnd = 2000 比 cwnd = 4000 更紧,发送窗口被 rwnd 限制为 2000。
第二步:分析已发未确认数据
| 段号 | 字节数 | 状态 |
|---|---|---|
| 段 1 | 1000 | ✅ 已 ACK 确认 |
| 段 2 | 1000 | ❌ 已发但未确认 |
已发未确认 = 1000 字节(仅段 2)。
第三步:算还可发送的最大字节数
第四步:用滑动窗口直观理解
发送窗口 = 2000
┌────────────┐
[已确认...|段2(1000)|空间(1000)|...]
↑ ↑ ↑
ack位置 已发 还可发接收方 ACK 段 1 后,发送窗口左端右移 1000 字节,新窗口为 [段 2 起点, 段 2 起点 + 2000)。其中 [段 2 起点, 段 2 起点 + 1000) 已发出(段 2,等 ACK),[段 2 起点 + 1000, 段 2 起点 + 2000) 还未发出可继续发——这一段长度 = 1000 字节。
最终答案是 A(1000)。
编者注(生僻术语):TCP 滑动窗口的"剩余可发"= 窗口 − 已发未确认。这个量在发送方反映为"还能继续输入到 socket 的字节数"——超过这个量 socket 写操作会阻塞。
接收方 rwnd 在 ACK 中通告,反映"我还能缓存多少字节";发送方 cwnd 由拥塞控制算法在本地维护,反映"网络拥塞容许多少";最终发送窗口取两者较小值,确保既不撑爆接收方、也不撑爆网络。