0%

计算机网络传输层01

传输层服务和协议

  • 传输层协议为运行在不同 Host 上的进程提供了一种逻辑通信机制
  • 端系统运行传输层协议
    • 发送方:将应用递交的消息分成一个或多个 segment 段,并向下传给网络层
    • 接收方:将接收到的 segment 段组装成消息,并向上交给应用层

传输层 vs 网络层

  • 网络层提供主机之间的逻辑通信机制
  • 传输层提供应用进程之间的逻辑通信机制
    • 位于网络层之上
    • 依赖于网络层服务
    • 对网络层服务进行(可能的)增强

Internet提供的传输层协议

TCP

可靠、按序的交付服务

  • 拥塞控制
  • 流量控制
  • 连接建立(链路可达)

UDP

不可靠的交付服务,基于尽力而为(Best-effort)的网络层,没有做可靠性方面的扩展。

两种服务均不提供延迟带宽的保证。

多路复用和多路分用

发送方的多路复用和接收方的多路分用(分解)。

发送方多路复用

从多个 socket 接收数据,为每块数据封装上头部信息,生成 segment,交给网络层。

接收方多路分用

传输层依据头部信息将收到的 segment 交给正确的 socket,即不同的进程。

分用的工作原理

主机接收到 IP 数据报(datagrame)

  • 每个数据报携带源 IP 地址、目的 IP 地址
  • 每个数据报携带一个传输层的段(segment)
  • 每个段携带源端口号和目的端口号

主机收到 segment 后,传输层协议提取 IP 地址和端口信息,将 segment 导向相应的 socket,实现分用。TCP 做更多的处理,网络层不关心端口号。

无连接的分用 UDP

  1. 主机 A 利用端口号99111,99222创建 socket
  2. UDP 的 socket 用二元组标识(目的 IP 地址,目的端口号)
  3. 主机 B 收到 UDP 段后,检查段中的目的端口号,将 UDP 段导向绑定在该端口号的 scoket
  4. 来自不同源 IP 地址或源端口号的 IP 数据报(只要目的端口号一样)被导向同一个 scoket

面向连接的分用 TCP

  1. TCP socket 用四元祖标识(源 IP 地址,源端口号,目的 IP 地址,目的端口号)
  2. 接收端利用所有的四个值将 segment 导向合适的 scoket
  3. 服务器可能同时支持多个 TCP socket
  4. WEB 服务器为每个客户端开不同的 scoket

UDP

基于 IP 协议,做了简单的扩展

  • 支持 复用/分用
  • 简单的错误校验
    将网络层的服务暴露给应用层,提供 Best effort服务,UDP 段可能丢失、非按序到达。

无连接

  • UDP 发送方和接收方之间不需要握手
  • 每个 UDP 段的处理独立于其他段

UDP 存在的价值

  • 无需建立连接(减少延迟)
  • 实现简单:无需维护连接状态
  • 头部开销小 (8 Bytes)
  • 没有拥塞控制:应用可更好的控制发送时间和速率,TCP 内部有拥塞控制,不完全听命于上层

问题:为什么有了链路层的错误校验还需要传输层的错误校验呢?

传输层提供的是端到端的服务,不能保证经过的所有链路都具有错误检测功能,即便所有链路都有错误检测功能,但在路由器进行存储转发的时候也有可能出错。

UDP用途

  • 用于流媒体应用
    • 容忍丢失
    • 速率敏感
  • DNS、SNMP
  • 在应用层上实现可靠数据传输
    • 在应用层增加可靠机制
    • 应用特定的错误恢复机制

UDP 校验和 checksum

检测 UDP 段在传输中是否发生错误(如位翻转)。

接收方计算所收到段的校验和并与报文中校验和字段对比

  • 不一致:检测出错误
  • 一致:没有检测出错误(可能有错误)

关于错误校验的能力问题,有些错误可以校验出来有些不行。

可靠数据传输原理

什么是可靠?不错、不丢、不乱。

可靠数据传输协议是网络的 Top 10 问题,信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性,可靠数据传输对应用层、传输层、链路层都很重要。

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)刻画传输协议

FSM

Rdt 1.0 可靠信道上的可靠数据传输

  • 底层信道完全可靠
    • 不会发送错误(bit error)
    • 不会丢弃分组
  • 发送方和接收方的 FSM 独立

Rdt1.0-FSM

Rdt 2.0 产生位错误的信道

  1. 底层信道可能翻转分组中的位(bit),利用校验和检测位错误。
  2. 如何从错误中恢复?
    1. 确认机制(Acknowledgements,ACK),接收方显式地告知发送方分组已正确接收
    2. NACK,接收方显式地告知发送方分组有错误
    3. 发送方收到 NACK 后,重传分组
  3. 基于这种重传机制的 rdt 协议称为 ARQ(Automatic Repeat reQuest) 协议

Rdt 2.0 中引入的新机制

  • 差错检测
  • 接收方反馈控制信息:ACK/NACK
  • 重传

Rdt 2.0 FSM

stop-wait 协议

Rdt2.0-FSM

Rdt 2.1 Rdt 2.2

Rdt 2.0 的缺陷

  1. 如果 ACK/NACK 消息发生错误/被破坏(corrupted)会怎么样?
    1. 为 ACK/NACK 增加校验和,检测并纠错(难度高)
    2. 发送方收到被破坏的 ACK/ANCK 时不知道接收方发生了什么,需要添加额外的控制信息(额外的消息仍然会坏掉)
    3. 如果 ACK/NACK 坏掉,发送方重传 (好)
    4. 不能简单的重传:产生重复分组 (待解决)
  2. 如何解决重复分组问题?
    1. 序列号(Sequence number):发送方给每个分组增加序列号
    2. 接收方丢弃重复分组

依然使用停等。
Stop and wait: sender sends one packet, then wait for receiver response.

Rdt 2.1 发送方, 应对 ACK/NACK 破坏,使用两个序列号

Rdt2.1-FSM-sender

Rdt2.1-FSM-recv

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

Rdt3.0-FSM-sender
发送方seq
发送方seq
timeout 太短,早熟。
发送方seq2

性能分析

Rdt 3.0 能够正确工作,但性能很差,是因为停等协议。

demo

demo
stop-wait

流水线机制与滑动窗口协议

流水线机制:提高资源利用率

pipeline

流水线协议

允许发送方收到 ACK 之前连续发送多个分组,就需要更大的序列号范围,发送方和接收方需要更大的存储空间来缓存分组。

滑动窗口协议

  • 滑动窗口协议:Sliding window protocol
  • 窗口
    • 允许使用的序列号范围
    • 窗口尺寸为 N:最多有 N 个等待确认的消息
  • 滑动窗口
    • 随着协议的运行,窗口在序列号空间内向前滑动
  • GBN、SR
    windown

Go-Back-N 协议

后退 N 帧协议

发送方

  • 分组头部包含 k-bit 的序列号,2的 k 次方的序列号
  • 窗口尺寸为N,最多允许 N 个分组未确认
    GBN
  • ACK(n): 确认到序列号n(包含n)的分组均已被正确接收。
    • 可能收到重复 ACK
  • 为空中的分组设置计时器(timer)
  • 超时 Timeout(n)事件:重传序列号大于等于n,还未收到 ACK 的所有分组

GBN-FSM

接收方

GBN-FSM-recv

  • ACK 机制:发送拥有最高序列号的、已被正确接收的分组的 ACK
    • 可能产生重复 ACK
    • 只需要记住唯一的 expectedseqnum
  • 乱序到达的分组
    • 直接丢弃,因为接收方没有缓存 (go back n)
    • 重新确认序列号最大的、按序到达的分组

GBN-seq

接收方没有窗口,没有缓存,效率差。

demo

数据链路层采用 GBN 协议,发送方已经发送了编号为 0-7 的帧,当计时器超时时,若发送方只收到0、2、3号帧的确认,则发送方需要重发的帧数是多少,分别
是哪几个帧?

根据 GBN 协议工作原理,GBN 协议的确认是累计确认,所以此时发送端需要重发的帧数是4个,一次分别是4、5、6、7帧。

Selective Repeat 协议

  • 接收方对每个分组单独进行确认
    • 设置缓存机制,缓存乱序到达的分组
  • 发送方只重传那些没收到 ACK 的分组
    • 为每个分组设置定时器
  • 发送方窗口
    • N 个连续的序列号
    • 限制已发送且未确认的分组

sr-window

SR

SR 协议困境

序列号空间大小与窗口尺寸需满足的关系?

发送方的窗口 + 接收方的窗口大小 <= 2的 k 次方(序列号位数)