Kapitel 3 传输层协议 (需配合PPT)

3.1 传输层需要解决的基本问题

  • 网络层——尽力而为 best effort,不保证可靠性
  • 出现:延迟、乱序、出错、丢失等情况

传输层需要解决

  • 可靠性问题
  • 复用和分用(对于多进程,共享IP和网络接口)

3.2 TCP/IP体系结构中传输层协议与服务

基本功能:复用分用、可靠性

传输层执行的动作

  • 发送端:将应用层的消息封装成传输层的数据单元,传递到网络层

  • 接收端:将从网络层接收的传输层数据单元,处理后交给应用层

  • 传输控制协议TCP(Transport Control Protocol)

    • 为进程间通信提供面向连接的、可靠的传输服务
    • 实现复用分用、差错检测、确认重传、流量控制等传输层功能
  • 用户数据报协议UDP(User Datagram Protocol)

    • 为进程间通信提供非连接的、不可靠的传输服务
    • 实现复用分用、差错检测等传输层功能

3.3 用户数据报协议(UDP)

  • 特点

发送方和接收方不需要握手过程

每个UDP数据单元(数据报)独立传输

提供复用分用功能和可选的差错检测功能

支持组播通信(点到多点通信)

不提供可靠性保证:无确认重传、可能有出错、丢失、乱序等现象

  • 数据包格式:长度、检验和

  • 复用分用:进程标识:目的IP地址+目的端口号

  • 差错检测

    • IPv4中可选,IPv6中必选
    • 发送端:利用自己产生的伪首部和发送的UDP数据报计算校验和
    • 接收端:利用自己产生的伪首部和接收的UDP数据报计算校验和
    • 伪首部:包含源IP地址、目的IP地址、协议类型等域段

校验和计算方法

发送端

  • 产生伪首部,校验和域段清0,将数据报用0补齐为16位整数倍
  • 将伪首部和数据报一起看成16位整数序列
  • 进行16 位二进制反码求和运算,计算结果取反写入校验和域段

接收端

  • 产生伪首部,将数据报用0补齐为16为整数倍
  • 按16位整数序列,采用16 位二进制反码求和运算
  • 如果计算结果位全1,没有检测到错误;否则,说明数据报存在差错

计算结果位全1,可能没错;计算结果有0,一定有错

伪首部不传输,0填充也不传输,接收方需自己形成伪首部进行校验

校验和计算最高位溢出的话加到最低位,最后求反

校验时直接算循环进位的加法,不需要单独提出校验和位比对。

  • 使用伪首部的目的是检验UDP数据报是否到达真正的目的地

  • 伪首部的使用破坏了层次划分的基本前提,即每一层的功能独立

    目的主机的IP地址UDP通常知道,源IP的使用需要通过路由选择决定

IP首部、ICMP、UDP、TCP都需要计算校验和,方法类似

  • 使用UDP服务的应用
    • 流媒体应用(实时音频和视频)通常使用UDP服务
      • 能够容忍一定的丢失
      • 对时延敏感
    • 其他使用UDP服务的应用
      • DNS
      • SNMP
    • 需要在UDP之上实现可靠传输,即在应用层增加可靠机制
  • 为什么提供UDP服务?
    • 不需要建立连接,建立连接需要增加延时,特别对于简单的交互应用
    • 协议简单:在发送端和接收端不需要维护连接状态
    • 数据报头部短,额外开销小
    • 无拥塞控制

3.4 可靠数据传输

  • 基本原理
    • 涉及多个层次(应用层、传输层、链路层)
    • 计算机网络 TOP 10 问题
  • rdt 可靠数据传输协议
  • 应用层若需要可靠数据传输,并且认为传输层及以下为可靠信道
  • 网络层是不可靠信道
  • 要在传输层实现可靠数据传输,则在传输层实现rdt协议
  • 使用有限状态机(FSM)描述发送端和接收端的状态和状态迁移
  • 考虑单向数据传输,控制信息可以双向传输

rdt没有考虑失序问题,TCP中可能发生失序问题

完全可靠通道上的可靠数据传输:rdt1.0

  • 下层通道是完全可靠的
    • 无位错误
    • 无分组丢失

具有位错误通道上的可靠数据传输:rdt2.0

假设下层通道可能造成某些位出现错误,不考虑丢失

自动重传请求

  • ACK 确认接收
  • NAK 出现错误,通知发送端需要重传

增加功能

  • 差错检测
  • 接收端反馈
  • 发送端重传

停等机制

存在问题

  • ACK/NAK受损:发送端无法确认接收端的状况,但不能简单重传(可能重复接收)
  • 处理重复接收问题
    • 发送端在每个分组中增加序列号
    • 如果无法判断是ACK或NAK,则重传当前的分组
    • 接收端丢弃重复的分组

rdt2.1:解决rdt2.0的问题

在rdt2.0基础上需要增加

  • 发送端在每个分组中增加序列号
  • 接收端根据序列号判断是否是重复的分组
  • 接收端在ACK/NAK分组中增加校验字段

rdt2.2:对rdt2.1的改进

  • 与rdt2.1功能相同,只使用ACK,不再使用NAK(NAK-free)
  • 接收端通过发送对最后正确收到的分组的ACK代替NAK
    • ACK中必须携带所确认分组的序列号
  • 发送端接收到重复的ACK,代表对当前分组的NAK,则
    • 重传当前的分组

rdt3.0:通道既有差错又有丢失

下层通道可能会有分组丢失(数据分组或ACK分组)

前面的校验和、序列号、ACK、重传机制等不足以解决丢失检测问题

解决方法:发送端等待一个合理的时间(需要一个定时器)

  • 如果未收到ACK,则重传当前的分组
  • 如果分组仅仅是被延迟,或是ACK丢失,会造成接收端重复接收
  • 接收端需要根据序列号判断重复的分组,并丢弃

性能问题(停等协议)

性能优化:使用流水线

流水线

在确认未返回之前允许发送多个分组

两种典型的流水线协议:

  • 回退N:Go-Back-N (GBN)
  • 选择重传:Selective Repeat (SR)
    • 发送端
      • 接收上层数据:如果发送窗口中有可用的序号,发送分组
      • 超时:重传分组n,重启定时器
      • 接收 ACK:n在区间内,将分组n标记已接受,如果是窗口中最小的未确认分组,则窗口向前滑动,基序号为下一个未确认分组的序号
    • 接收端
      • n在区间base,base+n-1内,发送 ACK 缓存失序分组,按序列到达的分组交付给上层,窗口前滑
      • n在区间base-n,base-1内,发送ACK

3.5 传输控制协议(TCP)

特点

  • 提供可靠服务:按序、可靠交付

    • 提供字节流服务,不识别消息边界
  • 可靠传输机制

    • 提供差错检测功能,正确接收返回确认
    • 使用序列号检测丢失和乱序
    • 超时重传机制,解决出错、丢失问题
    • 支持流水线机制,自适应窗口
  • 面向连接:发送数据前需要握手

    • 三次握手建立连接
    • 初始化参数 分配缓冲区
  • 提供复用分用功能

  • 点对点

  • 流量控制和拥塞控制

段格式

  • 头长度
  • 接收窗口通告
  • 标志位
  • 选项格式

复用分用

  • 通信之前通过三次握手建立 TCP 连接
    • 分配缓冲区,协商参数
  • 连接标识(四元组):源 IP、目的 IP、源端口、目的端口
  • 通过建立 TCP 连接为应用进程提供可靠的字节流服务

可靠数据传输

  • 基本机制
    • 发送端:发送数据、等待确认、超时重传
    • 接收端:差错检测、累积确认(按序正确接收到字节的下一个字节序列号)
  • 支持流水线机制
    • 发送序号:32位
    • 确认序号:32位
    • 每个字节都有序列号,对段的边界没有要求
  • 乱序段处理:未明确规定
    • 不缓存:处理简单、效率低
    • 缓存:效率高、复杂

思考:TCP 累积确认机制中,等待500ms确认的原因

1、收到数据包的序号前面还有需要接收的数据包。因为发送方发送数据时,并不是需要等上次发送数据被Ack就可以继续发送TCP包,而这些TCP数据包达到的顺序是不保证的,这样接收方可能先接收到后发送的TCP包(注意提交给应用层时是保证顺序的)。
2、为了降低网络流量,ACK有延迟确认机制。
3、ACK的值到达最大值后,又会从0开始。

流量控制

  • 流量控制的目的:避免发送端发送数据过快,接收端不能及时接收造成缓冲区溢出

    • 增加流控功能后,发送窗口还需要受接收能力的约束
  • 可变的滑动窗口:接收端利用接收窗口通告域段告知发送端接收端缓冲区剩余空间,发送端依据通告调整发送窗口大小

  • 滑动窗口发送端

    • LastByteAcked≤LastByteSent
    • LastByteSent≤LastByteWritten
    • 缓存的数据=LastByteWritten-LastByteAcked
  • 滑动窗口接收端

    • LastByteRead<NextByteExpected
    • NextByteExpected≤LastByteRcvd
    • 缓存的数据=LastByteRead-LastByteRead
  • 流量控制接收端ACK报文丢失,会造成死锁,如何解决?

    • 发送端在收到ACK报文window=0时启动定时器,超时发送较小的探测数据包
    • 接收端对每个发出的ACK报文启动定时器,超时未收到数据重发ACK
  • 接收窗口对性能的影响

    • 较小的缓冲区会影响网络的吞吐率
    • 过大的缓冲区会浪费主机的存储资源
  • 流量控制的性能问题,解决发送端和接收端有哪些解决策略?

    • 发送端每次“大车拉小货”:必须装载到一定的数据量才发
    • 接收端每次请求“货很少”:等待上层进程读取较多数据后再发送ACK请求

传输控制协议 TCP 连接管理

TCP连接开启

步骤一:TCP A端发送SYN段

  • 分配缓冲区,选择A→B初始序列号ISN

步骤二:TCP B端接收SYN段,回送SYN+ACK段

  • 分配缓冲区,选择B→A初始号序列

步骤三:TCP A端回送ACK

TCP连接关闭

步骤一:A端发送FIN段

  • A不再向B发送数据,但可以接收数据

步骤二:B端收到FIN,回送ACK

  • B仍可以向A发送数据

步骤三:B端发送FIN段,等待A返回ACK

步骤四:A收到FIN,回送ACK,等待两倍的段生存期关闭连接,B端收到ACK,关闭连接

## 3.6 理解网络拥塞

排队时延,丢弃

拥塞控制

  • 网络拥塞:主机发送的数据过多或过快,造成网络中的路由器(或其他设备)无法及时处理,从而引入时延或丢弃

  • 存储转发交换所采用的统计多路复用机制中,拥塞不可避免

    • 统计多路复用可以有效利用链路带宽资源
    • 轻度拥塞可以接受,中度或严重拥塞需要避免
  • 拥塞控制也是网络中的Top 10问题

  • 注意:拥塞控制与流量控制的区别

    拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:( 1 )慢开始、拥塞避免( 2 )快重传、快恢复。

    流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。

拥塞控制方法

端到端拥塞控制

  • 网络中无明确的反馈
  • 端系统通过观察丢失、延迟推断是否发生拥塞
  • TCP采用的拥塞控制策略

网络辅助的拥塞控制

  • 路由器提供到端系统的反馈
  • 例如:可以使用1位指示拥塞(如X.25, ATM)

3.7 TCP拥塞控制机制

目标:既不造成网络严重拥塞,又能更快地传输数据

  • 关键问题:发送多快比较恰当?

带宽探测:接收到ACK提高传输速率,发生丢失事件降低传输速率

  • ACK返回:说明网络并未拥塞,可以继续提高发送速率
  • 丢失事件:假设所有丢失是由于拥塞造成的,降低发送速率

TCP的拥塞控制的锯齿现象

TCP拥塞控制控制窗口

  • 采用基于窗口的方法,通过拥塞窗口的增大或减小控制发送速率

    LastByteSent -LastByteAcked≤CongestionWindow(cwnd)

    实际发送窗口取决于接收通告窗口和拥塞控制窗口中较小值

TCP拥塞控制:慢启动阶段

  • 初始拥塞窗口:cwnd=1一个TCP段大小(MSS)
  • 每个RTT,cwnd翻倍(指数增长)
  • 每接收到一个ACK,cwnd增1(MSS)
  • 当连接初始建立或报文段超时未得到确认时,TCP拥塞控制进入慢启动阶段
  • 特点:初始值小,增长速度快

TCP拥塞控制:拥塞避免阶段

  • 阈值ssthresh:拥塞窗口达到该阈值时,慢启动阶段结束,进入拥塞避免阶段

  • 每个RTT,cwnd增1(线性增长)

  • 注意:TCP使用字节计数,当收到ACK时,拥塞窗口计算如下:

    cwnd=cwnd+MSSMSScwndcwnd=cwnd+MSS*\frac{MSS}{cwnd}

TCP拥塞控制:丢失检测

  • 通过超时检测丢失:
    • 阈值ssthresh= cwnd/2
    • cwnd=1,进入慢启动阶段
  • 通过三次重复ACK检测丢失(TCP RENO算法):
    • 阈值ssthresh= cwnd/2
    • cwnd= ssthresh+3,进入线性增长(拥塞避免阶段)
    • 注:重复ACK指明网络仍可以交付一些报文段(拥塞不严重)
  • TCP Tahoe算法对于两种丢失情况均将cwnd设成1,并进入慢启动阶段

TCP拥塞控制:吞吐率问题讨论

  • TCP连接的吞吐率与拥塞窗口大小和RTT相关,我们假设:

    • 忽略慢启动阶段
    • 总有数据要发送
    • 设W为丢失事件发生时拥塞窗口的大小,W和RTT不变
    • 一个连接的平均吞吐率=0.75*W/RTT​
  • TCP长肥管道问题

    • 例如:报文段长度为1500字节,RTT为100毫秒,要获得10Gbps的吞吐率,要求平均窗口长度= 83333报文段

      100ms*10^6(bit/ms)/8(bit/byte)/1500byte=83333个报文段

    • 假设丢包率为L,则

      一个连接的平均吞吐量≈1.22*MSS/(RTT*sqrt(L))

    • 要获得10 Gbps的吞吐量,则LL≈2×10102×10^{−10}(非常小的丢失率,很难达到)

TCP拥塞控制:公平性问题讨论

  • 公平性的目标:如果有K个TCP连接共享带宽为R的瓶颈链路,每个连接应获得R/K的平均速率

  • 两个竞争的连接:

    假设两个连接RTT相等,从源主机到目的主机只有一条TCP连接

    RTT越小拥塞窗口增速越快

  • TCP与UDP是否公平?

    有些多媒体应用通常使用UDP,以恒定的速率发送音视频,能容忍一些丢失,避免TCP拥塞控制带来的速率限制及抖动

    UDP流量会压制TCP流量!(采用哪些方法可以解决?)

    在udp之上做其它协议时,实现拥塞控制,使得其与TCP流友好相处。

  • 多TCP连接的公平性问题

TCP拥塞控制:当前实现的有代表性的几个算法

  • New RENO算法
    • RENO仅考虑了每次拥塞发生时只丢失一个报文段的情形
    • New RENO主要解决一次拥塞多个报文段丢失,而造成的拥塞窗口和阈值多次折半问题(使TCP吞吐率降低)
  • Cubic算法
    • Linux内核2.6之后的默认TCP拥塞控制算法
    • 解决由于拥塞窗口的变化对RTT的依赖而造成的不公平性问题
  • BBR算法
    • 2016年由谷歌提出的,目前已集成到Linux 4.9内核中
    • BBR 算法不将出现丢包或时延增加作为拥塞的信号
    • BBR 算法周期性地探测网络的容量,交替测量一段时间内的带宽(BtlBw)极大值和时延(RTprop)极小值,将其乘积作为拥塞窗口大小

TCP拥塞控制:显示拥塞通知(ECN)

  • 一种网络辅助的拥塞控制机制,在RFC3168中定义
  • 路由器使用IP数据包首部TOS域段中的两位指示网络拥塞
  • 采用前向通知:网络拥塞通知携带到接收端
  • 接收端在返回的ACK中设置ECE位(TCP报文段的保留字段的低位),将网络拥塞通知给发送端