传输层(TCP、UDP、RDT详解)

目录

1.无连接传输:UDP

[UDP:User Datagram Protocol(用户数据报协议)](#UDP:User Datagram Protocol(用户数据报协议))

UDP:校验和

Internet校验和的例子

2.可靠数据传输(Rdt)的原理

可靠数据传输:问题描述

1.Rdt1.0:在可靠信道上的可靠数据传输

2.Rdt2.0:具有比特差错的信道

Rdt2.0:FSM描述

Rdt2.0:没有差错时的操作

Rdt2.0:有差错时的操作

3.Rdt2.1:序列号机制(处理出错的ACK/NAK)

Rdt2.1:讨论

Rdt2.1的运行

4.Rdt2.2:无NAK的协议

Rdt2.2的运行

5.Rdt3.0:具有比特差错和分组丢失(超时重传)的信道

Rdt3.0发送方

Rdt3.0的运行

Rdt3.0的性能

Rdt3.0:停-等操作

6.流水线协议

[6.1滑动窗口(slide window)协议](#6.1滑动窗口(slide window)协议)

发送窗口滑动过程:相对表示方法

[滑动窗口协议(Slide Window)](#滑动窗口协议(Slide Window))

6.2滑动窗口技术

6.3窗口互动(GBN与SR)

6.4流水线协议:总结

3.面向连接的传输:TCP

1.段结构

TCP报文段结构

TCP序号、确认号

TCP往返延时(RTT)和超时

2.可靠数据传输

TCP发送方(简化版)

TCP发送方事件

简化的TCP发送方

TCP重传

[产生TCP ACK的建议](#产生TCP ACK的建议)

快速重传

TCP快速重传

3.流量控制

TCP流量控制

4.连接管理

TCP2次握手

TCP3次握手

3次握手解决:半连接和接收老数据的问题

TCP3次握手的FSM

TCP:关闭连接


1.无连接传输:UDP

UDP:User Datagram Protocol(用户数据报协议)

  • 尽力而为的服务,报文段可能
    • 丢失
    • 送到应用进程的报文段乱序
  • 无连接
    • UDP发送端和接收端之间没有握手
    • 每个UDP报文段都被独立地处理
  • UDP被用于:
    • 流媒体(丢失不敏感、速率敏感、应用可控制传输速率)
    • DNS
    • SNMP(网络管理协议)
  • 在UDP上可行可靠传输
    • 在应用层增加可靠性
    • 应用特定的差错恢复

UDP:用户数据报协议

为什么要有UDP?

  • 不建立连接(连接会增加延迟)
  • 简单:在发送端和接收端没有连接状态
  • 报文段的头部很小(开销小)
  • 无拥塞控制和流量控制:UDP可以尽可能快的发送报文段
    • 应用 -> 传输速率 = 主机 -> 网络的速率

UDP:校验和

目标:检测在传输报文段中的差错(如:比特反转)

发送方:

  • 将报文段的内容视为16比特的整数
  • 校验和:报文段的加法和(1的不运算)
  • 发送方将校验和放在UDP的校验和字段

接收方:

  • 计算接收到的报文段的校验和
  • 检查计算出的校验和与校验和字段的内容是否相等
    • 不相等:检查到差错
    • 相等:没有检查到差错,但是可能还存在差错
      • 残存错误

Internet校验和的例子

注意:当数字相加时,在最高位的进位要回卷,再加到结果上

例子:两个16比特的的整数相加

最后得到的和的反码就是校验和

目标端:校验范围 (得到的结果和)+ 校验和 = 1111111111111111通过校验,否则没有通过校验

注:求和时,必须将进位回卷到结果上

2.可靠数据传输(Rdt)的原理

  • **rdt(可靠数据传输)**在应用层、传输层和数据链路层都很重要
  • rdt是网络Top 10问题之一
  • 信道的不可靠特点决定了rdt(可靠数据传输)的复杂性

可靠数据传输:问题描述

我们将:

  • 渐增式地开发可靠数据传输协议(rdt)的发送方和接收方
  • 只考虑单向数据传输
    • 但是控制信息是双向流动的!
  • 双向的数据传输问题实际上就是2个单向数据传输问题的综合
  • 使用**有限状态机(FSM)**来描述发送方和接收方

1.Rdt1.0:在可靠信道上的可靠数据传输

  • 下层的信道是完全可靠的(假设)
    • 没有比特差错
    • 没有分组丢失
  • 发送方和接收方的FSM
    • 发送方将数据发送到下层信道
    • 接受方从下层信道接收数据

总结:假设信道完全可靠,发送方与接收方只需要封装、解封装

2.Rdt2.0:具有比特差错的信道

  • 下层信道可能会出差错:将分组中的比特反转
    • 用校验和来检验比特差错
  • 问题:怎样从差错中恢复
    • 确认(ACK:Acknowledgement):接收方显式地告诉发送方已被正确接收
    • 否定确认(NAK:Negative Acknowledgement):接收方显式地告诉发送方分组发生了差错
      • 发送方收到NAK之后,发送方重传分组
  • Rdt2.0的新机制:采用差错控制编码进行差错检测
    • 发送方差错控制编码、缓存
    • 接收方使用编码检错
    • 发送方的反馈:控制报文(ACK、NAK):接收方 -> 发送方
    • 发送方收到反馈相应的动作

Rdt2.0:FSM描述

Rdt2.0:没有差错时的操作

Rdt2.0:有差错时的操作

rdt2.0的致命缺陷!-> rdt2.1

如果ACK/NAK出错?

  • 发送方不知道接收方发生了什么事情!
  • 发送方如何操作?
    • 重传?可能重复
    • 不重传?可能死锁(或出错)
  • 需要引入新的机制
    • 序号

处理重复

  • 发送方在每个分组中加入序号
  • 如果ACK/NAK出错,发送方重传当前分组
  • 接收方丢弃(不发送给上层)重复分组

停等协议发送方发送一个分组,然后等待接收方的应答

总结:下层信道可能会出错,所以引入校验和检测差错。如果接收方校验成功,发送ACK给发送方,发送方发送下一个分组;如果接收方校验失败,发送NAK给发送方,发送方重传上一个分组;存在问题:ACK与NAK可能在信道中出错

3.Rdt2.1:序列号机制(处理出错的ACK/NAK)

发送方处理出错的ACK/NAK

接收方处理出错的ACK/NAK

Rdt2.1:讨论

发送方

  • 在分组中加入序列号
  • 两个序列号(0,1)就足够了
    • 一次只发送一个未经确认的分组
  • 必须检测ACK/NAK是否出错(需要EDC)
  • 状态数变成了两倍
    • 必须记住当前分组的序列号是0还是1

接收方

  • 必须检测收到的分组是否是重复的
    • 状态会指示希望接收到分组的序号是0还是1
  • 注意:接收方并不知道发送方是否正确收到了其ACK/NAK
    • 没有安排确认的确认

Rdt2.1的运行

总结:在Rdt2.0的基础之上,引入序号。

  1. 发送方发送pkt0,接收方等待0并接收pkt0,接收方取出pkt0的序号进行校验,如果序号错误,返回NAK0;如果序号正确,校验校验和,如果校验错误,返回NAK0,否则返回ACK0,随后等待1;
  2. 发送方等待ACK0或NAK0,如果收到ACK0,就发出pkt1;如果收到NAK0,重发pkt0;如果收到的确认出错,也重发pkt0;
  3. 此时接收方如果在等待0,那么不会收到1;如果在等待1,如果接收到0,说明发出的确认错误了,重发一个ACK。

4.Rdt2.2:无NAK的协议

  • 功能同Rdt2.1,但是取消了NAK,只使用ACK(ack要编号)
  • 接收方对最后正确接收的分组发ACK,以替代NAK
    • 接收方必须显式地包含被正确接收分组的序号
  • 当收到重复的ACK(例如:再次收到ACK0),发送方与收到NAK采取相同的动作:重传当前分组
  • 为后面的一次发送多个数据单位做一个准备
    • 一次能够发送多个
    • 每一个的应答都有:ACK、NAK;麻烦
    • 使用对前一个数据单位的ACK,代替本单位的NAK
    • 确认信息减少一半,协议处理简单

Rdt2.2的运行

Rdt2.2:发送方和接受方片段

总结:使用ACK + 序号代替NAK。

5.Rdt3.0:具有比特差错和分组丢失(超时重传)的信道

新的假设:下层信道可能会丢失分组(数据或ACK)

  • 会死锁
  • 机制还不够处理这种状况
    • 校验和
    • 序列号
    • ACK
    • 重传

方法:发送方等待ACK一段合理的时间

  • 发送端超时重传:如果没有收到ACK -> 重传
  • 问题:如果分组(或ACK)只是被延迟了
    • 重传会导致数据重复,但是利用序列号已经可以处理这个问题
    • 接受方必须指明被正确接收的序列号
  • 需要一个倒计时定时器

Rdt3.0发送方

Rdt3.0的运行

  • 过早超时(延迟的ACK)也能正常工作,但是效率较低,一半的分组和确认是重复的
  • 设置一个合理的超时时间是很重要的

Rdt3.0的性能

  • Rdt3.0可以工作,但链路容量比较大的情况下,性能很差
    • 链路容量比较大,一次发一个PDU不能够充分利用链路的传输能力

例如:1Gbps的链路,15ms端到端的传播延迟,分组大小为1KB

Rdt3.0:停-等操作

总结:在Rdt2.2的基础上,加入了定时重传,防止了分组丢失

6.流水线协议

流水线:提高链路利用率

流水线协议

流水线:允许发送方在未得到对方确认的情况下一次发送多个分组

  • 必须增加序号的范围:用多个bit表示分组的序号
  • 在发送方/接收方要有缓冲区
    • 发送方缓冲:未得到确认,可能要重传
    • 接收方缓冲:上层用户取用数据的速率 != 接收到的数据速率;接收到的数据可能乱序,排序交互(可靠)
  • 两种通用的流水线协议:回退N步(GBN)和选择重传(SR)

6.1滑动窗口(slide window)协议

  • 发送缓冲区
    • 形式:内存中的一个区域,落入缓冲区的分组可以重新发送
    • 功能:用于存放已发送,但是没有得到确认的分组
    • 必要性:需要重发时可用
  • 发送缓冲区的大小:一次最多可以发送多少给未经确认的分组
    • 停止等待协议 = 1
    • 流水线协议 > 1,合理的值,不能很大,链路利用率不能超过100%
  • 发送缓冲区中的分组
    • 未发送的:落入缓冲区的分组,可以连续发送出去
    • 已经发送出去、等待对方确认的分组 :发送缓冲区的分组只有得到确认才能删除

|-------|-------|---------|
| 发送缓冲区 | 接收缓冲区 | 对应的协议 |
| 1 | 1 | 停止-等待协议 |
| 大于1 | 1 | CBN |
| 大于1 | 大于1 | SR |

发送窗口滑动过程:相对表示方法
  • 采用相对移动方法表示,分组不动
  • 可缓冲范围移动,代表一段可以发送的权利
滑动窗口协议(Slide Window)
  • 发送窗口:发送缓冲区内容的一个范围
    • 那些已发送但是未经确认分组的序号构成的空间
  • 发送窗口的最大值
  • 一开始:没有发送任何一个分组
    • 后沿 = 前沿
    • 之间为发送窗口的尺寸 = 0
  • 没发送一个分组,前沿移动一个单位

发送窗口的移动 -> 前沿移动

  • 发送缓冲区前沿移动的极限:不能超过发送缓冲区

发送窗口的移动 -> 后沿移动

  • 发送窗口后沿移动
    • 条件:收到老分组的确认
    • 结果:发送缓冲区罩住新的分组,来了分组可用发送
    • 移动的极限:不能超过前沿

6.2滑动窗口技术

  • 发送窗口(sending window)
  • 接收窗口(receiving window) = 接收缓冲区
    • 接收窗口用于控制哪些分组可以接受
      • 只有收到的分组序号落入接收窗口内才允许接收
      • 若序号在接收窗口之外,则丢弃
    • 接收窗口尺寸Wr = 1,则只能顺序接收
    • 接收窗口尺寸Wr > 1,则可以乱序排放
      • 但是提交给上层的分组,要排序
    • 例子:Wr = 1,在0的位置;只要有0号分组可以接受

向前滑动一个,罩在1的位置,如果来了第2号分组,则丢弃。

  • 接收窗口的滑动和发送确认
    • 滑动
      • 低序号的分组到来,接收窗口移动;
      • 高序号的分组乱序到,缓存但不交互(因为要实现Rdt,不允许失序),不滑动
    • 发送确认
      • 接收窗口尺寸 = 1;发送连续收到的最大的分组确认(累计确认)
      • 接收窗口尺寸 > 1;收到分组,发送的那个分组确认(非累计确认)

6.3窗口互动(GBN与SR)

正常情况下两个窗口的互动

异常情况下GBN的两个窗口互动

异常情况下SR的两个窗口互动

GBN协议与SR协议的异同

  • 相同之处
    • 发送窗口 > 1
    • 一次能够发送多个未经确认的分组
  • 不同之处
    • GBN:接收窗口尺寸 = 1
      • 接收端:只能顺序接收
      • 发送端:从表现来看,一旦一个分组没有发成功,如:1,2,3,4,5;假如1未发成功,234都发出去了,要返回1再发送;GB1。(234也需要重新发送)
    • SR:接收窗口尺寸 > 1
      • 接收端:可以乱序接收
      • 发送端:发送0,1,2,3,4,一旦1未成功,234都发出去了,无需重传,选择性发1(234无需再次发送)

6.4流水线协议:总结

Go-back-N

  • 发送端中最多在流水线中有N个未确认的分组
  • 接收端只是发送累计型确认cumulative ack
    • 接收端如果发现gap,不确认新到来的分组
  • 发送端拥有对最老的未确认分组的定时器
    • 只需设置一个定时器
    • 当定时器到时时,重传所有未确认分组

Selective Repeat

  • 发送端最多在流水线中有N个未确认的分组
  • 接受方对每个到来的分组单独确认indicidual ack(非累计确认)
  • 发送方为每个未确认分组保持一个定时器
    • 当超时定时器到时,只是重发到时的未确认分组

GBN:发送方扩展的FSM

GBN:接收方扩展的FSM

运行中的GBN

在接收端,乱序的不缓存;因此哪个n分组丢失了,GB到那个分组n,即使以后的分组传送都是正确的。

选择重传SR

  • 接收方对每个正确接收的分组,分别发送ACKn(非累计确认)
    • 接收窗口 > 1
      • 可以将缓存乱序的分组
    • 最终将分组按顺序交付给上层
  • 发送发只对那些没有收到ACK的分组进行重发-选择性重发
    • 发送方为每个未确认的分组设置一个定时器
  • 发送窗口的最大值(发送缓冲区)限制发送未确认分组的个数

选择重传

选择重传SR的运行

对比GBN和SR

窗口的最大尺寸

3.面向连接的传输:TCP

1.段结构

  • 点对点
    • 一个发送方,一个接收方
  • 可靠的、按照顺序的字节流
    • 没有报文边界
  • 管道化(流水线)
    • TCP拥塞控制和流量控制设置窗口大小
  • 全双工数据
    • 在同一连接中数据流双向流动
    • MSS:最大报文段大小
  • 面向连接
    • 在数据交换之前,通过握手(交换控制报文)初始化发送方、接收方的状态变量
  • 有流量控制
    • 发送发不会淹没接收方

TCP报文段结构

TCP序号、确认号

序号

  • 报文段首字节在字节流的编号

确认号

  • 期望从另一方收到的下一个字节的序号
  • 累计确认

简单telnet场景:

TCP往返延时(RTT)和超时

Q:怎样设置TCP超时?

  • 比RTT要长
    • 但是RTT是变化的
  • 太短:过早超时
    • 不必要的重传
  • 太长:对报文段丢失反应太慢,消极

Q:怎样估计RTT?

  • SampleRTT :测量从报文段发出到收到确认的时间
    • 如果有重传,忽略此次测量
  • SampleRTT会变化,因此估计的RTT应该比较平滑
    • 对几个最近的测量值求平均,而不是仅用当前的SampleRTT

设置超时

2.可靠数据传输

  • TCP在IP不可靠服务的基础上建立了Rdt
    • 管道化的报文段
      • GBN or SR
    • 累计重传(GBN)
    • 单个定时重传(GBN)
    • 是否可以接收乱序,没有规范
  • 通过以下时间触发重传
    • 超时(只重发那个最早的未确认段:SR)
    • 重复的确认
      • 例子:收到ACK50之后,又收到30个ACK50
  • 首先考虑简化TCP发送方
    • 忽略重复的确认
    • 忽略流量控制和拥塞控制

TCP发送方(简化版)

TCP发送方事件

简化的TCP发送方

TCP重传

产生TCP ACK的建议

快速重传

TCP快速重传

快速重传算法

3.流量控制

TCP流量控制

4.连接管理

在正式交换数据之前,发送方和接收方握手建立通信关系:

  • 同意建立连接(每一方都知道对方愿意建立连接)
  • 同意连接参数

TCP2次握手

Q:在网络中,2次握手建立连接是可行的吗?

  • 变化的延迟(连接请求的段没有丢,但是可能超时)
  • 由于丢失造成的重传(e.g.req_coon(x))
  • 报文乱序
  • 相互看不到对方

二次握手的失败场景

TCP3次握手

3次握手解决:半连接和接收老数据的问题

TCP3次握手的FSM

TCP:关闭连接

  • 客户端,服务器分别关闭它自己这一侧的连接
    • 发送FIN bit = 1的TCP段
  • 一旦接收到FIN,用ACK回应
    • 接收到FIN段,ACK可以和它自己发出的FIN段一起发送
  • 可以处理同时的FIN交换
相关推荐
千天夜10 小时前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
海绵波波1071 天前
Webserver(4.8)UDP、广播、组播
单片机·网络协议·udp
橘色的喵1 天前
Linux编程:DMA增加UDP 数据传输吞吐量并降低延迟
linux·udp·dma·网络驱动·低延迟·吞吐量·nic
UestcXiye2 天前
《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1)
c++·计算机网络·tcp
C++忠实粉丝2 天前
计算机网络socket编程(1)_UDP网络编程实现echo server
linux·服务器·网络·c++·网络协议·计算机网络·udp
重生之我是数学王子2 天前
网络编程 UDP编程 Linux环境 C语言实现
linux·c语言·开发语言·网络·网络协议·udp
Lingwl4 天前
Node.js UDP通信 dgram 组播
前端·网络·网络协议·udp·node.js
UestcXiye4 天前
《TCP/IP网络编程》学习笔记 | Chapter 2:套接字类型与协议设置
网络·c++·ip·tcp
Selina K4 天前
使用UDP实现发送和接收
qt·网络协议·udp
友友马6 天前
『 Linux 』网络传输层 - TCP(二)
linux·运维·网络·tcp