计网笔记-第三章:运输层

第三章-运输层 复习大纲

  • 传输层服务背后的原理
    • 多路复用,多路分解
    • 可靠数据传输
    • 流量控制
    • 拥塞控制
  • 因特网中的实例和实现
    • UDP
    • TCP

这一章东西是真的多,难度也比前两章高

3.1 传输层服务

在这里插入图片描述

  • 传输层:为两个不同的主机上运行的应用程序之间提供 逻辑通信
    • 传输层协议运行在端系统
      • 发送方:将应用程序报文分成 数据段 传递给网络层
      • 接收方:将数据段重新组装为 报文 传递到应用层
    • 不止一个传输层协议可以用于应用程序
      • 因特网:TCP & UDP
    • 对比传输层和网络层
      • 传输层:两个 进程 之间的逻辑通信——可靠,增强的网络层服务
      • 网络层:两个 主机 之间的逻辑通信
    • Internet 传输层协议
      • TCP:可靠按需递交
        1. 拥塞控制、流量控制、建立连接
        2. 但是不提供延迟保证、带宽保证
      • UDP:不可靠的无需传递
        • ”尽力传递“,IP的直接拓展

3.2 多路复用和多路分解

在这里插入图片描述

  • 多路复用:在发送主机处多路复用
    • 在多个套接字收集数据,用 首部封装数据 ,然后将报文段传递到网络层
  • 多路分解:在接收主机多路分解
    • 将接收到的数据段传递到正确的套接字

在这里插入图片描述

  • 多路分解的工作方式

    • 主机收到IP数据报
      • 每个数据报有 源IP地址、目的IP地址
      • 每个数据包搬运一个数据段
      • 每个数据段有 源和目的端口号(对于特定应用程序具有周知端口号)
    • 主机用IP地址和端口号指明数据段属于哪个合适的套接字
      在这里插入图片描述
  • 无连接多路分解

    • 用端口号创建套接字

      DatagramSocket ServerSocket1 = new DatagramSocket(38460);
      
    • UDP套接字由两个因素指定:目的IP地址+目的端口号

    • 主机收到UDP数据段后

      • 检查数据段中的目的端口号
      • 用端口号指示UDP数据段属于哪个套接字
    • 具有相同目的IP地址和目的端口号的IP数据报(无论源IP地址和源端口号是否一致),指向相同的套接字

在这里插入图片描述

  • 面向连接的多路分解

    • TCP套接字由4部分指定:源IP地址、源端口号、目的IP地址、目的端口号,接受主机使用这4个值将数据段定位到合适的套接字
    • 服务器主机可同时支持多个TCP套接字

在这里插入图片描述

P4,P5,P6可以用一个多线程服务器P4替代(此时一个P4服务器有3个端口)

3.3 UDP:无连接传输

  • UDP:”无修饰“”不加渲染的“”尽最大努力的“互联网传输层协议。

    • 无连接——UDP的接收者和发送者之间不需要握手、每个UDP数据段的处理独立于其他数据段

    • 缺点——数据段可能会:丢失、传递失序的报文到应用程序

    • 为什么会有UDP:

      • 简单、减少延迟(不需要建立连接)
      • 很小的数据段首部
      • 没有拥塞控制(因为UDP能够以尽可能快的速度传递)
    • 与 IP 的数据报服务相比,只增加了端口的功能和差错检查的功能

    • UDP的头部开销小,只有8个字节

      • 源端口(Source Port):2字节,发送方端口号。

      • 目的端口(Destination Port):2字节,接收方端口号。

      • 长度(Length):2字节,UDP报文的总长度(包括首部和数据部分)。

      • 校验和(Checksum):2字节,用于错误检测。

在这里插入图片描述

  • UDP面向报文——对应用程序交下来的报文保持完整性,保留了应用层数据的边界。

    • 发送方:UDP对应用程序交下来的数据报添加首部后,直接向下交付给IP层。一旦UDP将数据报发出,不保证其到达、不保证顺序、不重传。

    • 接收方:UDP从IP层接收到数据报后,去除首部,然后将数据报原封不动地交给上层应用进程。

      在这里插入图片描述

  • 优缺点总结:

    • 优点
    1. 低开销:由于UDP首部只有8个字节,协议开销很小,适合需要快速传输和低延迟的应用。
    2. 简单高效:没有连接建立和拆除的过程,减少了传输延迟,适合实时应用。
    3. 保留报文边界:UDP保留应用层报文的边界,方便应用程序处理
    • 缺点
    1. 无可靠性:UDP不保证数据报的到达、不保证顺序、不提供重传机制。需要应用层自行处理可靠性。
    2. 无流量控制:UDP不提供流量控制,可能导致网络拥塞或丢包。
    3. 无错误恢复:UDP只提供简单的校验和用于错误检测,但不提供错误恢复机制。
    • 适用场景
    1. 实时视频和音频流:例如视频会议、VoIP(网络语音)。
    2. 实时在线游戏:需要低延迟的数据传输。
    3. 简单的查询服务:如DNS查询。
    4. 广播和组播:需要将数据发送给多个接收方的场景。
  • UDP 校验和计算

    在这里插入图片描述

    • 并非100%可靠

    • 伪首部包含以下字段,总共12个字节:

      • 源IP地址(4字节)
      • 目的IP地址(4字节)
      • 保留字段(1字节):值为0
      • 协议字段(1字节):值为17,表示UDP协议
      • UDP长度字段(2字节):表示UDP数据报的总长度,包括首部和数据部分(与首部中的长度一致)
    • 处理方法

      • 发送发:将首部中的校验和暂时置为0(要参与运算的),将数据段看成16位的整数序列,计算校验和放入UDP的校验和域
      • 接收方:计算接收到数据段的校验和,检查与校验和域中的校验和是否一致(但就算一致也可能出错了)
    • 计算方法:

        1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0
        1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
        求和
      1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1
        进位回卷到结果上
        1 0 1 1 1 0 1 1 1 0 1 1 1 1 0 0  // 累加和
        求反
        0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1  // 校验和
      
    • 例题:

      源IP地址: 192.168.1.1(0xC0A80101)

      目的IP地址: 192.168.1.2(0xC0A80102)

      源端口: 12345(0x3039)

      目的端口: 80(0x0050)

      数据: “Hello”(对应的ASCII码:0x48656c6c6f)

      UDP长度= 8(头部)+ 5(数据)=13 (0x000D)

      1. 构建伪首部:
      源IP地址 | 目的IP地址 | 0 | 17 | UDP长度
      C0A8 | 0101 | C0A8 | 0102 | 0000 | 0011 | 000D
      
      1. 构建UDP头部和数据
      源端口 | 目的端口 | UDP长度 | 校验和
      3039 | 0050 | 000D | 0000
          
      数据部分:
      4865 | 6c6c | 6f00 // 不足补0
      
      1. 全部进行16位累加
      	C0A8 + 0101 + C0A8 + 0102 + 0000 + 0011 + 000D
          + 3039 + 0050 + 000D + 0000
          + 4865 + 6c6c + 6f00
      	= 5A31A
          回卷: A31A + 0005 = A31F
          取反: ~0xA31F = 0x5CE0
      
      1. 所以完整的UDP头部是:
      3039 | 0050 | 000D | 5CE0
      

3.4 可靠数据传输

  • 可靠传输协议(rdt,Reliable Transport Protocol)

  • Rdt1.0:完全可靠信道上的可靠数据传输

    • 没有bit错误、没有分组丢失

    • 发送方发送数据到下层信道,接收方从下层信道接收数据

      在这里插入图片描述

      注:虚线表示初始状态

      • rdt_send():由应用层调用,将数据交付给接收端的上层应用
      • udt_send():由 rdt 调用,将数据报通过不可信信道传输至接收端
      • rdt_rcv():当数据报到达接收端后被调用,用来接收packet
      • deliver_data():由 rdt 调用,将数据交付给上一层
      发送方FSM:
      1. 状态:等待数据

      (等待上层数据到达)

      • 事件:从上层接收到数据 → \rarr 数据打包 → \rarr 发送数据包 → \rarr 转移到状态:等待数据
      接收方FSM:
      1. 状态:等待数据

      (等待从信道接收数据包)

      • 事件:接收到数据包 → \rarr 数据开包 → \rarr 提交数据给上层 → \rarr 转移到状态:等待数据
  • Rdt2.0:具有bit错误的信道

    • 下层信道可能让传输分组中的bit受损——校验和将检测到bit错误

    • 如何从错误中恢复?(Acknowledgements & Negative Acknowledgements)

      • 确认(ACKs):接收方 明确告诉 发送方——分组接收正确
      • 否认(NAKs):接收方 明确告诉 发送方——分组接收错误
    • 相较于 rdt1.0 的新机制:

      • 差错检测(校验和):数据和头部的ACK/NAK都会计算校验和
      • 接收方的反馈 rcvr → \rarr sender(ACKs & NAKs)
    • FSM(有限状态机,Finite State Machine)规范:

      在这里插入图片描述

      • 有错 & 无错 的情况:

        在这里插入图片描述

        1. 没有错误就正常处理再返回ACK(左图)
        2. 有错误就直接返回NAK,然后sender再重新传,直到receiver返回ACK sender才进入等待态(右图)
      • 问题:只考虑了数据包传输时出现的bit错误,没考虑到ACK/NAK出现的问题!(ACK出现bit位翻转变成了NAK)

        • 解决方法:重发。
        • 但是重发可能重复,所以发送发给每个分组加一个序号,在ACK/NAK混淆时发送方重发当前分组,接收方丢弃重复的分组(就不向上传递了)—— 停等协议(发送方发送一个报文,然后等待接受方的响应)需要多少序号?——0,1 循环用
  • Rdt2.1:

    • 假设和行为:

      • 信道不丢包,但数据包可能损坏——发送方接收到损坏的ACK和NAK都会重新发送当前数据包,重启计时器
      • 使用序列号区分数据包
      • ACK和NAK都带有校验和,用于检测二者是否损坏

    在这里插入图片描述

    • case1:sender发送了一个0号数据包,receiver接收了,返回ACK但是翻转成了NAK,sender收到一个损坏的NAK——

    ​ 此时,sender重发0号数据包,receiver如果接收错误返回NAK要求重发(即使这里发的是重新发的0号包而不是期望的1号包);如果是接收正确,receiver会丢弃这个新的0号数据包,返回ACK,让sender发送1号包(下一个数据)。如果这个ACK又变成NAK则不断循环直到成功。

    ​ (下图右下角的处理)

    • case2:sender发送了一个0号数据包,receiver拒绝了,返回NAK但是翻转成了ACK,sender收到一个损坏的ACK——

    ​ 此时,sender重发0号数据包,如果接收错误还是要求重发;如果接受正确,receiver会返回ACK。

    ​ (下图左下角的处理)

    由于ACK/NAK带校验位,所以不会出现NAK翻转成ACK后sender错误地发送下一个数据包的情况

    • 在这里插入图片描述

    • 缺点:

      • 有NAK更复杂;并且即使引入了 NAK,接收方仍然需要处理重复的数据包,并发送冗余的 ACK,增加了处理负担。
      • 信道可能丢失数据包(receiver并不知道它的上一个ACK/NAK是否被sender正确收到)
      • 每次只能传1个包,效率低;重传效率低
  • Rdt2.2:不要NAK的协议

    在这里插入图片描述

    • ACK → \rarr ACK 0
    • NAK → \rarr ACK 1
  • Rdt3.0:考虑到包不仅可能会受损,还可能会丢失——引入超时重传
    在这里插入图片描述
    在这里插入图片描述

    • 发送方FSM如下(接收方FSM同2.2的):

      在这里插入图片描述

    • rdt3.0的停等操作:

      在这里插入图片描述

      性能分析:1Gbps链路,15ms传播时延,8000bit数据包,30ms RTT

      T t r a n s m i t = L R = 8000 b i t 1 0 9 b / s = 8 μ s T_{transmit}=\frac{L}{R}=\frac{8000bit}{10^{9}b/s}=8\mu s Ttransmit=RL=109b/s8000bit=8μs
      U s e n d e r = L / R R T T + L / R = 8 30 ∗ 1 0 3 + 8 = 0.00027 U_{sender}=\frac{L/R}{RTT+L/R}=\frac{8}{30*10^{3}+8}=0.00027 Usender=RTT+L/RL/R=30103+88=0.00027 // Utilization - 发送方忙于发送的时间占比(利用率)

      1KB/30ms 即 33KB/s(1Gbps链路)——这是一个网络协议严重影响链路资源利用的一个例子

    • 流水线技术:发送方允许发送多个 “在路上的”, 还没有确认的报文。(右图)——> 增加利用率

      在这里插入图片描述

      • 序号数目的范围必须增加

      • 在发送方/接收方必须有缓冲区

        在这里插入图片描述

      • 两个通用形式:GBN & 选择重传

    • GBN(Go-Back-N,回退 N 重传协议)

      在这里插入图片描述

      • 发送方:

        1. 在分组头中规定一个k位的序号
        2. 滑动窗口(允许连续未确认的报文)
      • 接收方:

        1. 为正确接收的最高序号的分组发送ACK(即上图一直发ACK1);由于没有接收缓冲区,所有只记住期待接收的序号
        2. 若接收到失序分组,丢弃,重发最高序号分组的ACK

        在这里插入图片描述

      • 问题:3,4,5都是正常的但还是会重复发

    • SR(Selective Repeat,选择重传协议)

      在这里插入图片描述

      • 窗格底部留在没有接收的分组处,在那之后收到的正常收(缓存);未被确认的报文超时后sender会重新发送,receiver收到后移动窗格到下一个没有接收的分组处,继续正常收。

        在这里插入图片描述

      • 发送方:

        1. 从上层收到数据后,如果下一个可用序号在发送方窗口内,则将数据打包发送,启动定时器
        2. 超时(n),重发分组n,重启定时器
        3. 收到ACK(n)在 [sendbase,sendbase+N-1]中
          • 标记分组n被接受
          • 如果n是最小的未确认分组,则提高窗口到下一个未被确认的序号
      • 接收方收到分组n时:

        1. 若n在窗口内 [rcvbase,rcvbase+N-1] :发送ACK(n)

          • 若接收后窗口是失序分组(不全),则继续缓冲

          • 若接收后窗口是有序分组,则交付上层(和已经缓冲的有序分组一起,提高窗口到下一个没有接受的分组)

            假如目前窗口是 [ , 3 , 4 , , 6],那么收到2之后,交付2,3,4,窗口变为[ , 6 , , , ]

        2. 若n在上一个窗口内 [rcvbase-N,rcvbase-1] :发送ACK(n)

      • 窗口大小 ≤ 序号空间大小 2 窗口大小 \leq \frac{序号空间大小}{2} 窗口大小2序号空间大小
      • 两难选择:

        在这里插入图片描述

        上图(b)情况中,由于没有收到ACK,sender的窗口不会挪动

Rdt 总结:

RDT 1.0: 无差错的信道

在这种情况下,假设信道是完美的,即没有数据包丢失、数据包损坏或数据包延迟。此时,数据传输协议不需要任何特殊机制,只需将数据从发送方传输到接收方即可。这种情况下的协议非常简单,因为信道本身是可靠的。

RDT 2.0: 信道可能发生数据损坏

在这种情况下,信道可能会导致数据损坏。为了检测和恢复这种情况,RDT 2.0引入了以下机制:

  • 校验和:发送方在数据包中加入校验和,接收方接收数据包后计算校验和并与数据包中的校验和比较,以检测是否存在数据损坏。
  • 确认(ACK)和否定确认(NAK):接收方在接收到数据包后发送ACK(确认)或NAK(否定确认)给发送方,以通知发送方数据是否正确接收。若接收到NAK,发送方重新发送数据包。
RDT 2.1: 处理NAK的改进

RDT 2.1在RDT 2.0的基础上,改进了对NAK的处理,使用ACK来确认接收,并使用序列号来区分不同的包。若接收到的数据包损坏,接收方将不发送ACK,发送方在超时后重新发送数据包。

RDT 2.2: 只使用ACK

RDT 2.2进一步改进,完全去除了NAK的使用,只通过ACK来确认数据包。接收方通过重复上一个正确接收的包的ACK来告知发送方当前数据包有误,发送方再重新发送该数据包。

RDT 3.0: 信道可能丢失数据包

在这种情况下,信道不仅可能损坏数据包,还可能丢失数据包。为了解决这个问题,RDT 3.0引入了超时重传机制:

  • 超时重传:发送方在发送数据包后启动定时器,若在定时器到期前未收到接收方的ACK,则认为数据包丢失或损坏,重新发送数据包。
  • 滑动窗口协议:用于提高传输效率,允许发送方在未接收到ACK的情况下连续发送多个数据包。
优化:GBN & SR

3.5 TCP:面向连接传输

集 GBN 和 SR 的优点

  • 概述:
    • 点到点
    • 可靠按序的字节流,没有信息边界
    • 流水线:TCP拥塞 & 流量控制设置窗口大小
    • 收发缓冲区
    • 全双工数据:同一个连接上的双向数据流(MSS:最大报文段长)
    • 面向连接:数据交换前先握手(交换控制信息),初始化收发方的状态
    • 流量控制:发送方不会淹没接收方

在这里插入图片描述

  • 报文段的结构:

    • TCP报文段首部格式

    在这里插入图片描述

    • 端口(2字节):运输层和应用层的服务接口。运输层的复用和分用都要通过端口实现。
    • 序号(4字节):本报文段所发送的数据的第一个字节的序号(TCP中传送的数据流中每个字节都会被编上一个序号)。
    • 确认号(4字节):期望收到对方的下一个报文段的数据的第一个字节的序号。
    • 数据偏移(0.5字节,4位):以32位(4字节)为单位来表示数据偏移(表示 TCP报文段的数据起始处距离TCP报文段的起始处有多远,也就是TCP首部的长度)。
    • 保留字段(0.75字节,6位):为以后使用,目前置为0.
    • 紧急URG(1位):URG=1,表示优先级高(Urgent)
    • 确认ACK(1位):ACK=1,字段才有效
    • 复位RST(1位):RST=1,TCP连接时出现严重错误,需要释放连接再重连(Reset)
    • 同步SYN(1位):SYN=1,表示这是一个连接请求or连接接收报文(Synchronize)
    • 终止FIN(1位):FIN=1,表示此报文段的发送端的数据已发送完毕,并要求释放运输链接(Finish)
    • 窗口(2字节):用来让对方设置发送窗口的依据,单位为字节
    • 校验和(2字节):计算时和UDP一样要加上12字节的伪首部(源IP + 目的IP + 0x0000 + 0x0011 + 2字节的TCP长度)
    • 紧急指针(0~4字节):指出本报文段中紧急数据的长度(紧急数据在报文段数据的最前面),单位为字节
    • 填充字段(和紧急指针加起来一共4字节):凑数的(TCP长度要是4的倍数字节那么长)
  • TCP的序号和确认

    在这里插入图片描述

    • 初始序号 ISN:随机选而不固定从0开始,防止网络中的攻击,增强TCP连接的安全性
    • 确认:期望从另一边收到的下一个字节的序号
    • 接收方如何处理失序的数据段?——TCP规范未明确规定,由编程人员处理。(PPT上就这么写的)
  • TCP往返时延的估计和超时

    • 设置的TCP超时值要比RTT长——但是RTT是变化的。

      • 太短:不成熟的超时,不必要的重传
      • 太长:对数据段丢失响应慢,效率低
    • 样本RTT:测量从报文段发送到收到确认的时间(忽略重传)。由于它是变化的,因此需要一个样本RTT均值(EstimatedRTT),对收到的样本RTT要进行如下均值处理:

      • 迭代公式: E s t i m a t e d R T T = ( 1 − α ) ∗ E s t i m a t e d R T T + α ∗ S a m p l e R T T EstimatedRTT=(1-\alpha)*EstimatedRTT+\alpha*SampleRTT EstimatedRTT=(1α)EstimatedRTT+αSampleRTT

      • 该均值计算称为“指数加权移动平均”,典型的 α = 0.125 \alpha=0.125 α=0.125

        在这里插入图片描述

    • 设置超时:EstimatedRTT + “安全余量”(类似波动率,EstimatedRTT越大,安全余量更大)

      • DevRTT 计算公式: D e v R T T = ( 1 − β ) ∗ D e v R T T + β ∗ ∣ S a m p l e R T T − E s t i m a t e d R T T ∣ DevRTT=(1-\beta)*DevRTT+\beta * |SampleRTT-EstimatedRTT| DevRTT=(1β)DevRTT+βSampleRTTEstimatedRTT

        ​ 典型的 β = 0.25 \beta=0.25 β=0.25

      • 设置超时时间间隔: T i m e o u t I n t e r v a l = E s t i m a t e d R T T + 4 ∗ D e v R T T TimeoutInterval=EstimatedRTT+4*DevRTT TimeoutInterval=EstimatedRTT+4DevRTT

      • 初始时令 T i m e o u t I n t e r v a l = 1 s TimeoutInterval=1s TimeoutInterval=1s

      • 获得第一个 S a m p l e R T T SampleRTT SampleRTT 后,令 E s t i m a t e d R T T = S a m p l e R T T EstimatedRTT=SampleRTT EstimatedRTT=SampleRTT D e v R T T = S a m p l e R T T 2 DevRTT=\frac{SampleRTT}{2} DevRTT=2SampleRTT

        T i m e o u t I n t e r v a l = E s t i m a t e d R T T + m a x ( G , 4 ∗ D e v R T T ) TimeoutInterval=EstimatedRTT+max(G,4*DevRTT) TimeoutInterval=EstimatedRTT+max(G,4DevRTT) ,其中 G 是用户设置的时间粒度,使得安全余量不小于某个常数

  • 可靠数据传输

    • TCP 在 IP 的不可靠服务上创建 rdt 服务
    • 流水线技术处理报文段
    • 累积确认(这会导致效率问题,解决方法 SACK 不考)
    • TCP 使用单个重发定时器
    • 触发重发:
      • 超时重发
      • 重复确认
  • 发送方事件:

    • 从应用程序接收数据后,用初始序号(报文中第一个数据字节在字节流中的位置编号,是随机生成的)创造一个报文。

    • 如果未启动定时器则启动定时器(因为定时器是 最早没有被确认的报文 发送时启动的),设置超时间隔 TimeoutInterval

    • 超时:

      • 重发导致超时的报文
      • 重新开始定时器
    • 收到确认

      • 如果 ACK 落在窗口内,则确认对应的报文并滑动窗口
      • 若还有未确认的报文,重启定时器

      在这里插入图片描述

  • 快速重传:

    超时重传的问题:超时周期太长,增加网络时延

    TCP采用的是累计确认机制,即当接收端收到比期望序号大的报文段时,便会重复发送最近一次确认的报文段的确认信号,我们称之为冗余ACK(duplicate ACK)。

    • 发送方可以在超时之前通过重复的 ACK 检测丢失的报文段

      • 发送方常常一个接一个地发送很多报文段
      • 若报文段丢失,那么发送方可能会收到很多重复的 ACK
    • 如果发送方收到 3次重复确认即 4 个对同一报文段地确认,因为第一个不算重复),则发送方认为该报文段之后的数据已经丢失。

    • 启动快速重传:在定时器超时之前重发丢失的报文段。

    • 以下内容参考:TCP的快速重传机制_快重传包括第一个-CSDN博客

      假设发送顺序为N,N+1,N+2,前一个发了N-1

      • 如果N没丢失,那么接收方的到达顺序有 A 3 3 = 6 A_{3}^{3}=6 A33=6 种可能:
      1. N,N+1,N+2 sender收到 1 个ACK(N)
      2. N,N+2,N+1 sender收到 1 个ACK(N)
      3. N+1,N,N+2 sender收到 2 个ACK(N)
      4. N+1,N+2,N sender收到 3 个ACK(N)
      5. N+2,N,N+1 sender收到 2 个ACK(N)
      6. N+2,N+1,N sender收到 3 个ACK(N)

      (也就是说 上面六种情况中,N 在第几个位置,那么 sender就会收到几个ACK(N) )

      • 如果N丢失了,那么就只有 A 2 2 = 2 A_{2}^{2}=2 A22=2 种情况了:
      1. N+1,N+2
      2. N+2,N+1

      (两种情况都相当于 N 在第三个位置,sender 收到 3 个ACK(N) )

      根据此规律,如果序列有N,N+1,N+2,N+3,那么:

      • 如果N丢失—— sender必定收到 4 个 ACK(N) ,即 3 个重复
      • 如果N没丢失—— sender 收到 4 个 ACK的概率是 A 3 3 A 4 4 = 25 % \frac{A_{3}^{3}}{A_{4}^{4}}=25\% A44A33=25%
      • 图1:某报文段的超时重传定时器溢出前重传丢失报文段

      在这里插入图片描述

      • 图2:图1对应地接收端缓存队列的窗口移动示意

      在这里插入图片描述

  • 产生TCP ACK 的建议

    接收方的事件TCP接收方行为
    1. 期望序号的报文段按序到达,所有在期望序号以前的报文段都被确认延迟ACK,等到500ms看是否有下一个报文段,如果没有,发送ACK
    2. 期望序号的报文段按序到达,另一个按序报文段等待发送立即发送单个累积ACK,确认两个有序的报文段
    3. 收到一个失序的报文段,高于期望的序号,检测到缝隙立即发送重复ACK,指出期望的序号
    4. 到达的报文段部分地 or 全部地填充接收数据间隔立即发送ACK,证实缝隙低端的报文段已经收到
  • TCP 流量控制

    TCP 连接的接收方有一个接收缓冲区,APP 可能从这个缓冲区中读出数据很慢

    • 速度匹配服务:发送速率和接收 APP 的提取速率匹配

    • 流量控制:发送发不能发送太多太快,让接收缓冲区溢出( v 发 ≈ v 收   & &   n 发 ≤ n 剩余容量 v_{发}\approx v_{收} \space \&\& \space n_{发}\leq n_{剩余容量} vv && nn剩余容量

    • 工作原理:

      在这里插入图片描述

    • 注:接收窗口的单位是字节

TCP连接管理
  • 建立连接:三次握手:(TCP在交换数据报文段之前在收发方之间建立连接,首先初始化TCP的序号、缓冲区流控信息)

    1. 客户发送TCP SYN报文段到服务器
    • 指定初始的序号
    • 没有数据
    1. 服务器接收 SYN,回复 SYN & ACK 报文段
      • 服务器分配缓冲区
      • 指定服务器的初始序号
    2. 客户接收 SYN/ACK ,回复 ACK 报文段,可能包含数据

    在这里插入图片描述

    双方都要对信道做至少一次的确认!

    第二步相当于 receiver 给 sender 一个关于信道 OK 的确认;

    第三步相当于 sender 给 receiver 一个关于信道 OK 的确认。

    “我说的话要有回应!”

    三次握手的主要目的是:确认双方选择的序号!

  • 关闭连接:四次挥手:客户关闭套接字

    1. 客户发送 TCP FIN 控制报文段到服务器

    2. 服务器接收到 FIN ,回复 ACK,进入半关闭连接状态。此状态下还能传数据,直到传完了再回复 FIN

    3. 服务器发送 FIN 到客户,启动 timer;

      客户接收 FIN ,回复 ACK。在此同时,客户端进入”time wait“状态(如下图标注处),等待结束时释放连接资源

    4. 服务器接收 ACK,服务器端连接关闭。客户端在上一步中等够 2msl没有收到服务器端报文也会关闭。

    为什么客户端要等 2*msl?

    因为如果服务器端没有收到第三步中 客户端发送的 ACK 报文,服务器就不能正常关闭连接。

    服务器端的 timer 超时之后会重新发送第三步的 FIN 报文,让客户端重发 ACK 报文。

    等的时间正好 = 传过去 + 传回来的最大值。

    在这里插入图片描述

    • TCP 客户端状态转换图:

      在这里插入图片描述

      客户端:从 CLOSED 态开始:

      1. 初始化 TCP 连接,发送 SYN,发起三次握手
      2. 收到 SYN & ACK,发送 ACK,发起 三次握手之三
      3. 收数据ing
      4. 发送 FIN,发起四次挥手
      5. 收到 ACK,不发任何东西(知道服务器端收到我的 FIN 报文了,让它把没发完的数据继续发)
      6. 收到 FIN,发送 ACK(此时服务器端的东西发完了)。继续等待 2*max segment time。发起 四次挥手之四

      2 msl 后无响应则断开连接

    • TCP 服务器端状态转换图:

      在这里插入图片描述

      服务器端:从 CLOSED 态开始:

      1. 监听 LISTEN

      2. 收到 SYN,回复 SYN & ACK,发起 三次握手之二

      3. 收到 ACK,结束三次握手,开始收发数据

      4. 发数据ing

      5. 收到客户端的 FIN 报文,回复 ACK,发起 四次挥手之二

      6. 发剩下没法玩的数据ing

      7. 数据发完之后发送 FIN 报文,等待客户端的 ACK 。发起 四次挥手之三

      超时后若没等到重新发 FIN 报文给客户端。

      收到 ACK 后断开连接

  • 拥塞控制

    • 场景1:

      • 假设两个发送者,两个接收者,一个路由器。不执行重发,带宽为 C。

      • 每个主机最大可达吞吐量 C/2,但是拥塞时延在 C/2 时达到无限大!

        在这里插入图片描述

    • 场景2:

      • 一个路由器,有限缓冲区

      • 发送方重发丢失的报文

      • 总是 λ i n = λ o u t \lambda_{in}=\lambda_{out} λin=λout (goodput)

      • 超时而没有丢失的报文重发——同样的 λ o u t \lambda_{out} λout 需要比完美情况更大的 λ i n ′ \lambda_{in}' λin

        • 拥塞的代价:重发(更多的工作)得到更好的吞吐量

        • 不必要的重发:链路需要运输多个分组的拷贝

        在这里插入图片描述

    • 场景3:

      • 4个发送方、多跳路径、超时/重发

        在这里插入图片描述

        λ i n \lambda_{in} λin λ i n ′ \lambda'_{in} λin 增加时,可能会发生以下情况:

        1. 拥塞增加:由于 λ i n \lambda_{in} λin λ i n ′ \lambda_{in}' λin 的增加,网络中的数据流量变大,可能导致路由器或交换机的输出链路出现拥塞。
        2. 数据包丢失:拥塞会导致缓冲区溢出,从而导致数据包丢失。这种情况会导致需要重传数据,进一步增加 λ i n ′ \lambda_{in}' λin
        3. 延迟增加:随着数据包在网络中等待传输的时间增加,数据传输的延迟也会增加。
        4. 网络效率下降:由于重发数据的增加,有效数据传输的比例降低,整体网络效率可能下降。
        5. 多跳路径影响:在多跳路径的情况下,拥塞不仅会影响当前链路,还会波及到其他相关链路,可能导致更广泛的网络性能下降。

        总结来说,当 λ i n \lambda_{in} λin λ i n ′ \lambda_{in}' λin 增加时,会导致网络拥塞、缓冲区溢出(数据包丢失)、延迟增加和整体网络效率下降。这些都是由于共享输出链路的带宽限制以及数据重发引起的。

        在这里插入图片描述

        拥塞的另一个代价:当分组丢失后,任何上游路由器的发送能力都浪费了

    • 拥塞控制的方法:

      • 端到端拥塞控制:
        1. 没有从网络中得到明确的反馈
        2. 采用 TCP 拥塞控制(检测数据包的丢失和延迟来判断网络是否拥塞)
      • 网络辅助的拥塞控制:
        1. 路由器通过单 bit 向端系统指示拥塞(使用一个位来指示网络中的拥塞状态)
        2. 指明发送者应该发送的频率

3.7 TCP 拥塞控制

  • 特点:

    • 端到端控制(没有网络辅助)
    • 发送方限制发送
    • 大体上, r a t e = C o n g W i n R T T B p s rate=\frac{CongWin}{RTT}Bps rate=RTTCongWinBps ,其中 CongWin(Congestion Window,阻塞窗口)是动态的、感知的网络拥塞的函数。
  • 发送方如何感知拥塞?

    • 超时 or 3个重复的ACK = 丢失事件 (超时、收到3个重复的ACK 通常作为网络拥塞的标志)
    • TCP 发送方在丢失事件发生后降低发送速率(CongWin)
  • 三个机制:

    • 慢启动
    • AMD:发送方增加发送速率,直到丢包发生,然后在丢包时再降低发送速率
    • 对拥塞事件作出反应
  • 具体参考:TCP的拥塞控制算法:慢启动算法、拥塞避免算法,快速重传与超时重传算法,快速恢复算法_tcp慢启动和拥塞避免-CSDN博客(前面的概念讲解可以看看,后面的 TCP 对丢包的处理和PPT不太一样)

  • 必考一道大题

sshthresh(slow start threshold,慢启动阈值)

  • 怎样理解不同的丢包事件?

    • 3个重复ACK表名网络具有传输一些数据段的能力
    • 在三个重复的确认之前超时,那么说明网络传输能力差,更严重!
  • 超时重传时的拥塞控制算法:

    sshthresh=原CongWin/2

    新CongWin=1

  • 快速重传时的拥塞控制算法

    sshthresh=原CongWin/2

    对于CongWin的处理有两种方式:

    1. 新CongWin=1(Tahoe版本)
    2. 新CongWin=原CongWin/2 + 3(Reno版本),此时会直接进入拥塞避免状态
  • PPT例子:

    • 三种考法:

      1. 用文字描述概念

      2. 画or分析 图/表格

      3. 给出图/表格,用文字描述事件(如 第8~9RTT发生什么事了?)

        在这里插入图片描述

在这里插入图片描述

上图字有点小:

​ 在 线性增长阶段,一个 RTT 内,不论收到多少个ACK,CongWin都只会+1。慢启动阶段同理。

  • 总结:

    • 当CongWin低于阈值,慢启动,指数级增长
    • 当CongWin高于阈值,拥塞避免,线性增长
    • 快速重传(3次重复ACK)——阈值置为CongWin/2,CongWin置为1或者阈值+3(Reno:快速恢复阶段,此时每收到一个重复的ACK拥塞窗口增加1MSS,如果收到新的ACK则拥塞窗口置成阀值)
    • 超时——阈值置为 CongWin/2 ,CongWin置为1
  • TCP 平均吞吐量:0.75 W/RTT

    假设忽略慢启动

    • 在丢失发生时窗口大小为 W,吞吐量是 W/RTT
    • 丢失发生后,窗口降为 W/2,吞吐量为 0.5 W/RTT
    • 则 平均吞吐量为 0.75 W/RTT
  • TCP 未来

    • 例:1500字节的数据段,RTT=100ms,希望10Gbps吞吐量。要求窗口大小 W=83333个报文段。

    • 按照一个连接的平均吞吐量公式(L为丢包率): 1.22 ∗ M S S R T T ∗ L \frac{1.22*MSS}{RTT*\sqrt{L}} RTTL 1.22MSS

      则选择的TCP为到达 10 Gbps的吞吐量,要求 L = 2 ∗ 1 0 − 10 L=2*10^{-10} L=21010,即每500万个报文段只允许丢失一个报文段

      用于高速的TCP的新版本时必要的
      (照着PPT写的,应该不考)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值