传输层服务和协议
- 传输层协议为运行在不同 Host 上的进程提供了一种逻辑通信机制
- 端系统运行传输层协议
- 发送方:将应用递交的消息分成一个或多个 segment 段,并向下传给网络层
- 接收方:将接收到的 segment 段组装成消息,并向上交给应用层
传输层 vs 网络层
- 网络层提供主机之间的逻辑通信机制
- 传输层提供应用进程之间的逻辑通信机制
- 位于网络层之上
- 依赖于网络层服务
- 对网络层服务进行(可能的)增强
Internet提供的传输层协议
TCP
可靠、按序的交付服务
- 拥塞控制
- 流量控制
- 连接建立(链路可达)
UDP
不可靠的交付服务,基于尽力而为(Best-effort)的网络层,没有做可靠性方面的扩展。
两种服务均不提供延迟,带宽的保证。
多路复用和多路分用
发送方的多路复用和接收方的多路分用(分解)。
发送方多路复用
从多个 socket 接收数据,为每块数据封装上头部信息,生成 segment,交给网络层。
接收方多路分用
传输层依据头部信息将收到的 segment 交给正确的 socket,即不同的进程。
分用的工作原理
主机接收到 IP 数据报(datagrame)
- 每个数据报携带源 IP 地址、目的 IP 地址
- 每个数据报携带一个传输层的段(segment)
- 每个段携带源端口号和目的端口号
主机收到 segment 后,传输层协议提取 IP 地址和端口信息,将 segment 导向相应的 socket,实现分用。TCP 做更多的处理,网络层不关心端口号。
无连接的分用 UDP
- 主机 A 利用端口号99111,99222创建 socket
- UDP 的 socket 用二元组标识(目的 IP 地址,目的端口号)
- 主机 B 收到 UDP 段后,检查段中的目的端口号,将 UDP 段导向绑定在该端口号的 scoket
- 来自不同源 IP 地址或源端口号的 IP 数据报(只要目的端口号一样)被导向同一个 scoket
面向连接的分用 TCP
- TCP socket 用四元祖标识(源 IP 地址,源端口号,目的 IP 地址,目的端口号)
- 接收端利用所有的四个值将 segment 导向合适的 scoket
- 服务器可能同时支持多个 TCP socket
- WEB 服务器为每个客户端开不同的 scoket
UDP
基于 IP 协议,做了简单的扩展
- 支持 复用/分用
- 简单的错误校验
将网络层的服务暴露给应用层,提供 Best effort服务,UDP 段可能丢失、非按序到达。
无连接
- UDP 发送方和接收方之间不需要握手
- 每个 UDP 段的处理独立于其他段
UDP 存在的价值
- 无需建立连接(减少延迟)
- 实现简单:无需维护连接状态
- 头部开销小 (8 Bytes)
- 没有拥塞控制:应用可更好的控制发送时间和速率,TCP 内部有拥塞控制,不完全听命于上层
问题:为什么有了链路层的错误校验还需要传输层的错误校验呢?
传输层提供的是端到端的服务,不能保证经过的所有链路都具有错误检测功能,即便所有链路都有错误检测功能,但在路由器进行存储转发的时候也有可能出错。
UDP用途
- 用于流媒体应用
- 容忍丢失
- 速率敏感
- DNS、SNMP
- 在应用层上实现可靠数据传输
- 在应用层增加可靠机制
- 应用特定的错误恢复机制
UDP 校验和 checksum
检测 UDP 段在传输中是否发生错误(如位翻转)。
接收方计算所收到段的校验和并与报文中校验和字段对比
- 不一致:检测出错误
- 一致:没有检测出错误(可能有错误)
关于错误校验的能力问题,有些错误可以校验出来有些不行。
可靠数据传输原理
什么是可靠?不错、不丢、不乱。
可靠数据传输协议是网络的 Top 10 问题,信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性,可靠数据传输对应用层、传输层、链路层都很重要。
可靠数据传输协议基本结构:接口
rtd_send()
: 被上层应用调用,将数据交给 rdt 以发送给对方udt_send()
: 被 rdt 调用,在不可靠信道上向接收方传输数据rdt_rcv()
: 当数据到达接收方信道时被调用deliver_data()
: 接收方可靠传输协议向上层应用交付数据
rdt_send()
and deliver_data()
都是单向的,应用层只关收发数据,下方传输层负责数据可靠性。
udt_send()
and rdt_rcv()
都是双向的,在不可靠的数据信道上需要双向的控制信息流动。
可靠数据传输协议
- 渐进地设计可靠数据传输协议的发送方和接收方
- 考虑单向数据传输,但控制信息双向流动
- 利用状态机(Finite State Machine,FSM)刻画传输协议
Rdt 1.0 可靠信道上的可靠数据传输
- 底层信道完全可靠
- 不会发送错误(bit error)
- 不会丢弃分组
- 发送方和接收方的 FSM 独立
Rdt 2.0 产生位错误的信道
- 底层信道可能翻转分组中的位(bit),利用校验和检测位错误。
- 如何从错误中恢复?
- 确认机制(Acknowledgements,ACK),接收方显式地告知发送方分组已正确接收
- NACK,接收方显式地告知发送方分组有错误
- 发送方收到 NACK 后,重传分组
- 基于这种重传机制的 rdt 协议称为 ARQ(Automatic Repeat reQuest) 协议
Rdt 2.0 中引入的新机制
- 差错检测
- 接收方反馈控制信息:ACK/NACK
- 重传
Rdt 2.0 FSM
stop-wait 协议
Rdt 2.1 Rdt 2.2
Rdt 2.0 的缺陷
- 如果 ACK/NACK 消息发生错误/被破坏(corrupted)会怎么样?
- 为 ACK/NACK 增加校验和,检测并纠错(难度高)
- 发送方收到被破坏的 ACK/ANCK 时不知道接收方发生了什么,需要添加额外的控制信息(额外的消息仍然会坏掉)
- 如果 ACK/NACK 坏掉,发送方重传 (好)
- 不能简单的重传:产生重复分组 (待解决)
- 如何解决重复分组问题?
- 序列号(Sequence number):发送方给每个分组增加序列号
- 接收方丢弃重复分组
依然使用停等。
Stop and wait: sender sends one packet, then wait for receiver response.
Rdt 2.1 发送方, 应对 ACK/NACK 破坏,使用两个序列号
Rdt 2.1 vs Rdt 2.0
发送方
- 为每个分组增加了序列号
- 两个序列号(0,1)就够用,为什么?因为采用的是停等协议
- 需校验 ACK/NACk 消息是否发送错误
- 状态数量翻倍
- 状态必须记住当前的分组序列号
接收方
- 需判断分组是否是重复
- 当前所处状态提供了期望收到分组的序列号
- 注意:接收方无法知道 ACK/NACK 是否被发送方正确收到
Rdt 2.2 无 NACK 的消息协议
真的需要两种确认消息(ACK + NACK)吗? Rdt 2.2 与 Rdt 2.1 功能相同,但是只使用 ACK。
实现方式
- 接收方通过 ACK 告知最后一个被正确接收的分组
- 在 ACK 消息中显式的加入被确认分组的序列号
- 发送方收到重复 ACK 后,采取与收到 NACK 消息相同的动作,重发当前分组
比如发送方发送序列号1,但是接收方收到错误的数据,此时接收方发送序列号0的ACK,发送方收到重复ACK就会重发分组
Rtd 3.0
如果信道既可能发送错误,也可能丢失分组,检验和、序列号、ACK、重传还够用吗?
解决方法:发送方等待”合理”的时间重传。
- 如果没收到 ACK,重传
- 如果分组或 ACK 只是延迟而不是丢失呢
- 重传会产生重复,序列号机制能够处理
- 接收方需在 ACK 中显式告知所确认的分组
- 需要定时器
Rdt 3.0 FSM
timeout 太短,早熟。
性能分析
Rdt 3.0 能够正确工作,但性能很差,是因为停等协议。
demo
流水线机制与滑动窗口协议
流水线机制:提高资源利用率
流水线协议
允许发送方收到 ACK 之前连续发送多个分组,就需要更大的序列号范围,发送方和接收方需要更大的存储空间来缓存分组。
滑动窗口协议
- 滑动窗口协议:Sliding window protocol
- 窗口
- 允许使用的序列号范围
- 窗口尺寸为 N:最多有 N 个等待确认的消息
- 滑动窗口
- 随着协议的运行,窗口在序列号空间内向前滑动
- GBN、SR
Go-Back-N 协议
后退 N 帧协议
发送方
- 分组头部包含 k-bit 的序列号,2的 k 次方的序列号
- 窗口尺寸为N,最多允许 N 个分组未确认
- ACK(n): 确认到序列号n(包含n)的分组均已被正确接收。
- 可能收到重复 ACK
- 为空中的分组设置计时器(timer)
- 超时 Timeout(n)事件:重传序列号大于等于n,还未收到 ACK 的所有分组
接收方
- ACK 机制:发送拥有最高序列号的、已被正确接收的分组的 ACK
- 可能产生重复 ACK
- 只需要记住唯一的 expectedseqnum
- 乱序到达的分组
- 直接丢弃,因为接收方没有缓存 (go back n)
- 重新确认序列号最大的、按序到达的分组
接收方没有窗口,没有缓存,效率差。
demo
数据链路层采用 GBN 协议,发送方已经发送了编号为 0-7 的帧,当计时器超时时,若发送方只收到0、2、3号帧的确认,则发送方需要重发的帧数是多少,分别
是哪几个帧?
根据 GBN 协议工作原理,GBN 协议的确认是累计确认,所以此时发送端需要重发的帧数是4个,一次分别是4、5、6、7帧。
Selective Repeat 协议
- 接收方对每个分组单独进行确认
- 设置缓存机制,缓存乱序到达的分组
- 发送方只重传那些没收到 ACK 的分组
- 为每个分组设置定时器
- 发送方窗口
- N 个连续的序列号
- 限制已发送且未确认的分组
SR 协议困境
序列号空间大小与窗口尺寸需满足的关系?
发送方的窗口 + 接收方的窗口大小 <= 2的 k 次方(序列号位数)