计算机网络5
接上节——计算机网络4
停止等待协议
数据传输时的四种情况:
-
正常:DATA0 → ACK0 → DATA1 → ACK1
作用:说明“发一帧、等确认、再发下一帧”的基本节拍(流量控制)。 -
数据帧出错(收到但校验错)
处理:B 回 NAK0(或沉默不回 ACK)→ A 重传 DATA0。
体现:差错控制;错误由 NAK/无ACK + 超时触发重传。 -
数据帧丢失(B完全没收到)
处理:A 等不到 ACK 超时 → 重传 DATA0。
体现:超时重传机制保证最终送达。 -
确认帧(ACK)丢失(B已收妥数据)
处理:A 等不到 ACK 超时 → 重传 DATA0;
B 用序号(0/1) 识别为重复帧,丢弃数据但再发 ACK0。
体现:序号判重确保“不重复上交、仍可继续前进”。
event_type
-
frame_arrival —— 帧到达(有效帧/ACK 到来)。
-
cksum_err —— 校验错误(收到的帧损坏)。
-
timeout —— 超时(未在规定时间内收到期望的 ACK)
1) Protocol 1 — Utopia(理想单工)
假设:信道无差错;接收端处理能力无限。
目的:演示最基本的“从网络层取包→封成帧→发出”的单向数据流。
机制:无 ACK、无计时器、无序号、无流量控制。
核心循环:
-
Sender:
from_network_layer → s.info=buffer → to_physical_layer
(一直泵数据) -
Receiver:
wait_for_event(frame_arrival) → from_physical_layer → to_network_layer
意义:仅用于引入接口与数据路径;不具备工程可用性。
2) Protocol 2 — Stop-and-Wait(流量控制,信道仍“理想”)
假设:信道无差错;但接收端缓存/处理速度有限。
目的:防止发送端“淹没”接收端——流量控制。
机制:发一帧就停等接收端的“许可”(dummy/确认帧)再发下一帧;仍无差错控制。
核心循环:
-
Sender:发一帧 →
wait_for_event
(等对端许可) -
Receiver:
from_physical_layer → to_network_layer → to_physical_layer(s)
(回一个允许/占位确认,唤醒发送端)
关键词:停—等 = 每次只允许1个在途帧(窗口=1),解决流量控制而非可靠性。
3) Protocol 3 — Stop-and-Wait ARQ(有噪声单工,可靠传输)
假设:信道可能丢帧/出错/ACK丢失。
目的:在不可靠信道上实现可靠、按序、恰好一次交付。
新增机制:
-
序列号(1 bit:0/1)——判重与判新;
-
ACK(肯定确认)——对已收妥的帧确认;
-
计时器(timeout)——ACK没来就重传;
-
事件集:
frame_arrival / cksum_err / timeout
。
核心循环: -
Sender:装帧(带
seq
) → 发送 →start_timer
→wait_for_event
→ 收到匹配ACK
则stop_timer
& 换下一个;否则超时重发。 -
Receiver:到达就校验;若
r.seq==frame_expected
则上交并切换期望号;无论是否重复都回ACK
(ack=1-frame_expected
)。
关键词:ACK + Timer + Seq(0/1) 三件套 = 可靠的停—等。
4) Protocol 4 — One-Bit Sliding Window(双工,捎带确认)
假设:有噪声;双向同时通信(两端同构)。
目的:在全双工下维持可靠传输与更高信道利用率。
新增机制:
-
仍是窗口=1(本质还是停—等),但双向;
-
捎带确认(piggybacked ACK):把对对方上一帧的 ACK 塞进自己要发的帧头;
-
两端都维护:
next_frame_to_send
(发端窗口左边界)与frame_expected
(收端窗口左边界)。
核心循环(两端对称): -
处理入站:若
r.seq==frame_expected
→ 上交并inc(frame_expected)
;若r.ack==next_frame_to_send
→ 停表并inc(next_frame_to_send)
; -
构造出站帧:
s.seq=next_frame_to_send; s.ack=1-frame_expected; to_physical_layer; start_timer
。
关键词:双工 + 捎带ACK + 1bit序号;效率高于单向停—等。
滑动窗口协议
三种
one-Bit
后退N帧
在 Go-Back-N 协议 中:
-
发送方窗口大小 = N(可以连续发送 N 帧,不必等每个确认)
-
接收方只按顺序接收:
-
如果收到了期望的帧(按顺序的),就发送 ACK;
-
如果收到乱序帧(比如期望1却收到了2),就丢弃并重复发送上一个确认号(ACK0)。
-
-
当发送方超时或收到累计确认时:
-
若帧 i 超时,则从 i 开始的所有未确认帧都要重发。
-
✅ 累积确认机制:
若收到 ACK k,表示 0~k 的所有帧都已正确收到。
数据链路层采用后退 N 帧(GBN)协议,发送方已发送了编号为 0~7 的帧。
当计时器超时时,若发送方只收到了 0、2、3 号帧的确认,则发送方需要重发的帧是 4567
名称 | 类型/取值 | 含义/作用 | 出现场景 |
---|---|---|---|
MAX_PKT | 常量(如 1024) | 网络层包packet.data 的最大字节数 | protocol.h |
MAX_SEQ | 常量(=1 于 Prot.3/4) | 序列号最大值(一位序号 → 取值 {0,1}) | Prot.3/4 |
boolean | enum {false,true} | 自定义布尔类型 | protocol.h |
seq_nr | unsigned int | 序列号/确认号的数值类型 | 全部协议 |
frame_kind | enum {data, ack, nak} | 帧类别:数据/确认/否认 | protocol.h |
event_type | enum {frame_arrival, cksum_err, timeout} (Prot.2 为 {frame_arrival} ) | wait_for_event() 可能返回的事件类型 | Prot.2/3/4 |
packet | struct { unsigned char data[MAX_PKT]; } | 网络层交付的数据单元 | 全部协议 |
frame | struct { frame_kind kind; seq_nr seq; seq_nr ack; packet info; } | 链路层帧:头部(kind/seq/ack ) + 负载(info ) | 全部协议 |
名称 | 类型/取值 | 含义/作用 | 出现场景 |
---|---|---|---|
next_frame_to_send | seq_nr (0/1) | 发送窗口左边界 / “将要发送或刚发送的帧号”。收到匹配 ACK 后自增(0↔1) | Prot.3/4 |
s | frame | 发送缓冲帧:待发或等待确认的那一帧(用于可能的重传) | Prot.1/2/3/4 |
buffer | packet | 当前待发的网络层包(由 from_network_layer() 取来) | 全部协议(发送端) |
event | event_type | wait_for_event() 返回的当前事件 | 全部协议 |
s.info | packet | 装入待发数据(帧负载) | 全部协议 |
s.seq | seq_nr | 待发帧的序列号 | Prot.3/4 |
s.ack | seq_nr | 捎带确认号(Prot.4)或专用 ACK 帧的确认号(Prot.3) | Prot.3/4 |
名称 | 类型/取值 | 含义/作用 | 出现场景 |
---|---|---|---|
frame_expected | seq_nr (0/1) | 接收窗口左边界 / “期望收到的下一帧编号”;收到期望帧后自增(0↔1) | Prot.3/4 |
r | frame | 接收缓冲帧:刚从物理层取到的帧 | Prot.1/2/3/4 |
r.info | packet | 接收帧中的数据,交给网络层 | 全部协议(接收端) |
r.seq | seq_nr | 收到帧的序列号,与 frame_expected 比较判新/重复 | Prot.3/4 |
r.ack | seq_nr | 收到帧中携带的确认号(用于发送端停止计时、推进窗口) | Prot.3/4 |
s.ack (接收端构造) | seq_nr = 1 - frame_expected | 要回给对端的确认号(确认上一帧) | Prot.3/4(回 ACK) |
名称 | 含义/作用 | 触发/配合的变量 |
---|---|---|
wait_for_event(&event) | 阻塞等待事件(frame_arrival / cksum_err / timeout ) | event |
start_timer(s.seq) / stop_timer(s.ack) | 为已发送但未确认的帧启动/停止超时计时 | s.seq 、s.ack 、next_frame_to_send |
to_physical_layer(&s) / from_physical_layer(&r) | 发/收 帧 的抽象接口 | s 、r |
from_network_layer(&buffer) / to_network_layer(&r.info) | 取/交 网络层包 的接口 | buffer 、r.info |
inc(k) | 序号循环自增宏:k = (k < MAX_SEQ) ? k+1 : 0 | next_frame_to_send 、frame_expected |