传输层
文章目录
传输层概述
-
传输层协议为运行在不同Host上的进程提供了一种逻辑通信机制
-
端系统运行传输层协议
发送方:将应用递交的信息分成一个或多个的Segment,并向下传给网络层
接收方:将接收到的segment组装成消息,并向上交给应用层。
-
传输层可以为应用提供多种协议,如Internet的TCP/UDP
传输层 VS 网络层
-
网络层:提供主机之间的逻辑通信机制
-
传输层:提供应用进程之间的逻辑通信机制
位于网络层之上
依赖于网络层服务
对网络层服务进行增强
Internet传输层协议
- 可靠、按序的交付服务(TCP):拥塞控制、流量控制、连接建立
- 不可靠的交付服务(UDP):基于“尽力而为”的网络层,没有做(可靠性方面的)扩展
- 两种服务均不保证:延迟、带宽
多路复用和多路分用
UDP
-
基于Internet IP协议,实现了复用/分用、简单的错误校验等功能。
-
尽力而为(“Best effort”)服务,UDP段可能丢失、非按序到达
-
无连接,UDP发送方和接收方之间不需要握手,每个UDP段的处理独立于其他段
-
UDP为什么存在?
无需建立连接(减少延迟)
实现简单:无需维护连接状态
头部开销少
没有拥塞控制:应用可更好地控制发送时间和速率
-
常用于流媒体应用,容忍丢失、速率敏感
-
UDP还用于DNS、SNMP
-
在UDP上实现可靠数据传输?
在应用层增加可靠性机制
应用特定的错误恢复机制
-
UDP校验和(checksum)
目的:检测UDP段在传输中是否发生错误(如位翻转)
发送方:将段的内容视为16-bit整数,校验和计算,计算所有整数的和,进位加在和的后面,将得到的值按位求反,得到校验和,发送方将校验和放入校验和字段
接收方:计算所收到段的校验和,将其与校验和字段进行对比,不相等的话表示检测出错误,相等表示没有检测出错误(但可能有错误)
-
校验和计算示例
可靠数据传输原理
-
什么是可靠?不错、不丢、不乱
-
可靠数据传输协议
可靠数据传输对应用层、传输层、链路层都很重要
网络Top-10问题之一
信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性
-
可靠数据传输协议基本结构:接口
-
渐进地设计可靠数据传输协议的发送方和接收方
-
只考虑单向数据传输,但控制信息双向流动
-
利用状态机(Finite State Machine,FSM)刻画传输协议
Rdt 1.0:可靠信道上的可靠数据传输
Rdt2.0
-
底层信道可能翻转分组中的位(bit)
利用校验和检测位错误
-
如何从错误中恢复?
确认机制(ACK):接收方显式地告知发送方分组已正确接收
NAK:接收方显式地告知发送方分组有错误
发送方收到NAK后,重传分组
-
基于这种重传机制的rdt协议称为ARQ协议
-
Rdt 2.0 中引入的新机制
差错检测
接收方反馈控制信息:ACK/NAK
重传
-
FSM规约
-
无错误场景
-
有错误场景
Rdt 2.1 和 2.2
-
如果ACK/NAK消息发生错误/被破坏会怎么样?
为ACK/NAK增加校验和,检错并纠错
发送方收到被破坏的ACK/NAK时不知道接收方发生了什么,添加额外的控制消息
如果ACK/NAK坏掉,发送方重传
不能简单的重传:产生重复分组
-
如何解决重复分组问题?
序列号:发送方给每个分组增加序列号
接收方丢弃分组
-
Rdt 2.1:发送方,应对ACK/NAK破坏
-
Rdt 2.1:接收方,应对ACK/NAK破坏
-
Rdt 2.2:无NAK消息协议
-
Rdt 2.2 FSM片段
Rdt 3.0
-
如果信道既可以发生错误,也可能丢失分组,怎么办?
"校验和 + 序列号 + ACK + 重传"够用吗?
显然是不够的
-
解决方法:发送方等待“合理”时间
如果没收到ACK,重传
如果分组或ACK只是延迟而不是丢了,重传会产生重复,序列号机制能够处理,接收方需在ACK中显式告知所确认的分组
需要定时器
-
Rdt 3.0 发送方FSM
-
Rdt 3.0 示例:正确接收和丢失分组
-
Rdt 3.0 示例:ACK丢失和等待时间过短
-
Rdt 3.0性能分析
-
导致性能差的主要原因——停等操作
流水线机制与滑动窗口协议
-
流水线机制——提高资源利用率
-
流水线协议——允许发送方在收到ACK之前连续发送多个分组
更大的序列号范围
发送方和/或接收方需要更大的存储空间以缓存分组
-
滑动窗口协议
滑动窗口协议:Sliding-window protocol
窗口,允许使用的序列号范围,窗口尺寸为N,最多有N个等待确认的消息
滑动窗口,随着协议的运行,窗口在序列号空间内向前滑动
滑动窗口协议:GBN,SR
Go-Back-N(GBN)协议
-
分组头部包含k-bit序列号
-
窗口尺寸为N,最多允许N个分组未确认
-
ACK(n):确认到序列号n(包含n)的分组均已被正确接收,可能收到重复ACK
-
为空中的分组设置计时器(timer)
-
超时Timeout(n)事件:重传序列号大于等于n,还未收到ACK的所有分组
-
发送方扩展FSM
-
接收方扩展FSM
-
ACK机制:发送拥有最高序列号的、已被正确接收的分组的ACK,可能产生重复ACK,只需要记住唯一的expectedseqnum
-
乱序到达的分组,直接丢弃接收方没有缓存,重新确认序列号最大的、按序到达的分组
-
GBN示例
Selective Repeat(SR) 协议
-
GBN有什么缺陷?
-
接收方对每个分组单独进行确认,设置缓存机制,缓存乱序到达的分组
-
发送方只重传那些没收到ACK的分组,为每个分组设置定时器
-
发送方窗口,N个连续的序列号,限制已发送且未确认的分组
-
Selective Repeat:发送方/接收方窗口
-
SR协议
-
SR协议示例
-
SR协议:困境
TCP
TCP概述
-
点对点,一个发送方,一个接收方。
-
可靠的、按序的字节流
-
流水线机制,TCP拥塞控制和流量控制机制,设置窗口大小。
-
发送方/接收方缓存
-
全双工,同一连接中能够传输双向数据流
-
面向连接,通信双方在发送数据之前必须建立连接,连接状态只在连接的两端维护,在沿途节点中并不维护状态。
-
TCP连接包括:两台主机上的缓存、连接状态变量、socket等。
-
流量控制机制
-
TCP段结构
-
TCP:序列号和ACK
序列号:序列号指的是segment中第一个字节的编号,而不是segment的编号。建立TCP连接时,双方随机选择序列号。
ACKs:希望接收到的下一个字节的序列号。累计确认,该序列号之前的所有字节均已被正确接收到
接收方如何处理乱序到达的Segment?TCP规范中没有规定,由TCP的实现者做出决策
TCP可靠数据传输概述
-
TCP在IP层提供的不可靠服务基础上实现可靠数据传输服务。
-
流水线机制
-
累积确认
-
TCP使用单一重传定时器
-
触发重传的事件,超时、收到重复ACK
-
渐进式:暂不考虑重复ACK,暂不考虑流量控制,暂不考虑拥塞控制
-
TCP RTT和超时
问题:如何设置定时器的超时时间?
大于RTT,但是RTT是变化的,设置的过短会导致不必要的重传,过长会导致对段丢失时间反应慢
问题:如何估计RTT?
SampleRTT:测量从段发出去到收到ACK的时间,忽略重传。SampleRTT变化,测量多个SampleRTT,求平均值,形成RTT的估计值 EstimatedRTT
EstimatedRtt = (1-a)*EstimatedRtt + a*EstimatedRtt
指数加权移动平均,典型值:0.125定时器超时时间的设置:EstimatedRtt + “安全边界” 。EstimatedRtt 变化大——>较大的边界
-
TCP发送方事件
从应用层收到数据:创建Segment,序列号是Segment第一个字节的编号,开启计时器,设置超时时间:TimeOutInterval
超时:重传引起超时的Segment,重启定时器
收到ACK:如果确认此前未确认的Segment,更新SendBase。如果窗口中还有未被确认的分组,重新启动定时器。
-
TCP重传示例
-
TCP ACK生成
-
快速重传机制
TCP的实现中,如果发生超时,超时时间间隔将重新设置,即将超时时间间隔加倍,导致其很大,重发丢失的分组之前要等待很长时间。
通过重复ACK检测分组丢失,Sender会背靠背地发送多个分组,如果某个分组丢失,可能会引发多个重复的ACK
如果sender收到对同一数据的3个ACK,则假定该数据之后的段已经丢失,快速重传,在定时器超时之前即进行重传
-
TCP流量控制
TCP连接管理
-
TCP sender和receiver在传输数据前需要建立连接
-
初始化TCP变量,Seq.#,Buffer和流量控制信息
-
Client:连接发起者 Socket clientSocket = new Socket(“hostname”,“prot number”);
-
Server:等待客户连接请求 Socket connectionSocket = welcomeSocket.accept();
-
连接需要三次握手
-
关闭连接
TCP拥塞控制
-
什么是TCP拥塞控制
TCP拥塞控制的目标是最大化利用网络上瓶颈链路的宽带。简单来说是将网络链路比喻成一根水管,如果我们希望尽可能地使用网络传输数据,方法就是给水管注水。为了保证水管不会爆管,TCP维护一个拥塞窗口cwnd(congestion window),用来估计在一段时间内这条链路(水管中)可以承载和运输的数据(水)的数量,拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化,但是为了达到最大的传输效率,我们该如何知道这条水管的运送效率是多少呢?
一个简单的方法就是不断增加传输的水量,直到水管破裂为止(对应到网络上就是发生丢包),用TCP的描述就是:
只要网络中没有出现拥塞,拥塞窗口的值就可以再增大一些,以便把更多的数据包发送出去,但只要网络出现拥塞,拥塞窗口的值就应该减小一些,以减少注入到网络中的数据包数。
-
常见的TCP拥塞控制算法
Reno
Reno适用于低延时、低带宽的网络,它将拥塞控制的过程分为四个阶段:慢启动、拥塞避免、快重传和快恢复。对应的状态如下所示:
- 慢启动阶段思路是不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小,在没有出现丢包时每收到一个ACK就将拥塞窗口大小加1(单位是MSS,最大单个报文段长度),每轮次发送窗口增加一倍,呈指数增长,若出现丢包,则将拥塞窗口减半,进入拥塞避免阶段;
- 当窗口达到慢启动阈值或出现丢包时,进入拥塞避免阶段,窗口每轮次加1,呈线性增长;当收到对一个报文的三个重复的ACK时,认为这个报文的下一个报文丢失了,进入快重传阶段,要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认;
- 快重传完成后进入快恢复阶段,将慢启动阈值修改为当前拥塞窗口值得一半,同时拥塞窗口值等于慢启动阈值,然后进入拥塞避免阶段,重复上诉过程。
BBR
BBR算法不将出现丢包或时延增加作为拥塞得信号,而是认为当网络上的数据包总量大于瓶颈链路带宽和时延的乘积时才出现了拥塞,所以BBR也称为基于拥塞的拥塞控制算法(Congestion-Based Congestion Control),其适用网络为高带宽、高时延、有一定丢包率的长肥网络,可以有效降低传输时延,并保证较高的吞吐量,与其他两个常见算法发包速率对比如下:
BBR算法周期性地探测网络的容量,交替测量一段时间内的带宽极大值和时延极小值,将其乘积作为拥塞窗口的大小,使得拥塞窗口始的值始终与网络的容量保持一致。
所以BBR算法解决了两个比较主要的问题:
- 在有一定丢包率的网络链路上充分利用带宽。适合高延迟、高带宽的网络链路。
- 降低网络链路上的buffer占用率,从而降低延迟。适合慢速接入网络的用户。
-
总结
目前有非常多的TCP的拥塞控制协议,例如:
- 基于丢包的拥塞控制:将丢包视为出现拥塞,采取缓慢探测的方式,逐渐增大拥塞窗口,当出现丢包时,将拥塞窗口减小,如Reno、Cubic等。
- 基于时延的拥塞控制:将时延增加视为出现拥塞,延时增加时增大拥塞窗口,延时减小时减小拥塞窗口,如Vegas、FastTCP等。
- 基于链路容量的拥塞控制:实时测量网络带宽和时延,认为网络上报文总量大于带宽时延乘积时出现了拥塞,如BBR。
- 基于学习的拥塞控制:没有特定的拥塞信号,而是借助评价函数,基于训练数据,使用机器学习的方法形成一个控制策略,如Remy。
从使用的角度来说,我们应该根据自身的实际情况来选择自己机器的拥塞控制协议(而不是跟风BBR),同时对于拥塞控制原理的掌握(尤其是掌握Reno的控制机理和几个重要阶段)可以加强对于网络发包机制的了解。
-
总结
目前有非常多的TCP的拥塞控制协议,例如:
- 基于丢包的拥塞控制:将丢包视为出现拥塞,采取缓慢探测的方式,逐渐增大拥塞窗口,当出现丢包时,将拥塞窗口减小,如Reno、Cubic等。
- 基于时延的拥塞控制:将时延增加视为出现拥塞,延时增加时增大拥塞窗口,延时减小时减小拥塞窗口,如Vegas、FastTCP等。
- 基于链路容量的拥塞控制:实时测量网络带宽和时延,认为网络上报文总量大于带宽时延乘积时出现了拥塞,如BBR。
- 基于学习的拥塞控制:没有特定的拥塞信号,而是借助评价函数,基于训练数据,使用机器学习的方法形成一个控制策略,如Remy。
从使用的角度来说,我们应该根据自身的实际情况来选择自己机器的拥塞控制协议(而不是跟风BBR),同时对于拥塞控制原理的掌握(尤其是掌握Reno的控制机理和几个重要阶段)可以加强对于网络发包机制的了解。