目录
UDP:User Datagram Protocol(用户数据报协议)
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的基础之上,引入序号。
- 发送方发送pkt0,接收方等待0并接收pkt0,接收方取出pkt0的序号进行校验,如果序号错误,返回NAK0;如果序号正确,校验校验和,如果校验错误,返回NAK0,否则返回ACK0,随后等待1;
- 发送方等待ACK0或NAK0,如果收到ACK0,就发出pkt1;如果收到NAK0,重发pkt0;如果收到的确认出错,也重发pkt0;
- 此时接收方如果在等待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无需再次发送)
- GBN:接收窗口尺寸 = 1
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
- 可以将缓存乱序的分组
- 最终将分组按顺序交付给上层
- 接收窗口 > 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交换