科大计网之:传输层
Weiquan Huangchp3-1 概述
- 传输层为应用层的不同主机的不同应用进程之间提供逻辑通信;发送方会将应用层的报文分为报文段,然后传给网络层,而接收方会将报文段重组为报文,传给应用层;对于数据丢失、乱序等问题有自己的解决方案
- 传输层提供的复用和解复用功能起到一个汇总和分发的功能,即将通向相同主机的应用层报文汇总发向同一个主机,同时将发来的复用报文拆解分发给不同的应用进程
- 传输层TCP协议提供拥塞控制、流量控制、建立连接的额外加强功能,UDP不提供
- 传输层不可以解决非本层的问题,比如带宽、延迟等问题(受限于下层或者传输链路)
chp3-2 多路复用和解复用
多路复用实际上是指,当应用层需要通过传输层发送报文的时候,传输层会将报文先和本地port和目标port封装成为一个TCP/UDP SDU,然后往网络层传输的时候再添加一个本地IP和目标IP的头部,便于网络层的寻址;解复用是指传来的实体通过IP+port来进行socket的查找和定位,然后将数据传给正确的socket
这里还是解释一下,一个socket是在一个进程process上运行的,而一个process是一个应用程序,在TCP中相同的目标主机和端口由于会有不同的源主机和端口,因此一个服务端的一个端口是可以被多个应用进程监听的,因为有多个socket在这个主机的这个端口;而UDP的socket只和自己本地的主机和端口绑定,因此这个端口就只能被一个进程监听了
chp3-3 无连接传输 UDP
前面对于其特点,适用范围的已经介绍的差不多了,下面介绍一个校验和的机制
UDP报文存有一个校验和,在检验传输内容是否有误的时候会通过将UDP报文进行一个16比特整数“进位回滚”的累加,得到一个校验范围内的累加和;这个累加和再和校验和进行进位回滚相加,若最终结果为16位全1,则通过校验
“进位回滚”累计示意图:
chp3-4 可靠数据传输(rdt)原理
问题
传输层需要给应用层提供可靠的服务,但是传输层依赖的网络层服务是不可靠的,可能的问题是丢包、乱序、传送错误等;下面会逐步解决这些问题
rdt2.x:信道出错
- rdt2.0:接收方通过校验和检验传输内容是否有差错,返回ACK和NAK表示接受和不接受,发送方根据反馈分别进行下一个包的传递/重传当前包
- rdt2.1:考虑到ACK/NAK也会传输错误,加入一个“若返回给发送方的反馈为未定义值,直接认为是NAK进行旧包重传;同时由于每个包自己带有序列号,即使成功传输的包被重传,接收方也会丢弃并且发送该包对应序列号的ACK
- rdt2.2:考虑到之后有同时传送多个包的机制,每个包都分ACK/NAK数据类型会比较多,规定接收方对最后正确接受的分组发ACK,比如pkg1接受失败,则发送ACK0,表示pkg1的失败,那么pkg1需要重传;也就是说,ACKN的发送意味着pkgN的成功和pkg(N+1)的失败
rdt3.0:分组丢失
发送方如果等待一段时间后无任何来自接收端的响应,那么意味着或许发送方发送丢包,或者接收方响应丢包;在超时之后需要重发包
虽然不合适的定时会导致尚未接收到响应就定时重发(然后姗姗来迟的响应又会让发送方再发一次包),但是由于接收方有记录pkg的序列号,因此不会发生重复包传递到应用层的问题,但是路径上会有重复传送的包的整个节奏
性能:链路利用率很低,因为这相当于send-and-wait策略,只有一个包ACK了另一个包才会发送,那么如果本身发送包的时间很短,但是在链路中传播时间较长,那么就相当于从北京到上海的铁路只运行一辆动车的来回,链路利用率极低
流水线协议
允许发送方在未得到对方确认的情况下一次发送多个分组,提高链路的利用率
- 必须增加序号的范围:用多个bit位表示分组的序号,这是为了缓冲区大小的设立
- 在发送方和接收方均需建立缓冲区
- 发送方缓冲:未得到确认需重传
- 接收方缓冲:解决乱序问题,提供可靠服务;上层用户取用数据的速率和接收到的数据速率不一定相同
通用的模型是 滑动窗口(slide windows)协议,有发送缓冲区和接受缓冲区
- 发送缓冲区:落入缓冲区的分组可以发送,里面分组的状态分为未发送的分组和已发送未确认的分组
- 发送窗口:发送缓冲区的子集,存放已发送未确认的分组
发送窗口可以在发送窗口满、发送缓冲区有多余分组且队头分组确认接受/发送窗口有容量容纳发送缓冲区分组的情况下发生前沿的前进;可以在队头分组确认接受的情况下发生后沿的前进
- 接受窗口=接收缓冲区:接收窗口用于控制哪些分组可以被接收,若传送来的分组在接收窗口外则被丢弃
- 若RW=1,则只能顺序接受
- 若RW>1,则可以乱序接受,但是提交给应用层的需要是顺序打包的
send and wait(rdt3.0) | GBN(Go-Back-N) | SR(Selective repeat) | |
---|---|---|---|
send window | 1 | >1 | >1 |
receive window | 1 | 1 | >1 |
advantage | 无脑 | 简单且接收方缓存所需资源比较少 | 出错时代价小 |
disadvantage | 链路利用率低 | 一旦出错,回退N步代价大 | 复杂且接收方缓存所需资源多 |
使用范围 | 不好用 | 出错率低场所 | 链路容量大不适合重传大量包 |
- GBN协议
- 发送端最多有N个未确认的已发送分组
- 接收端只发送“累积性确认”,即当前按顺序接收到的最大分组序列号的ACK,不确认断层的乱序新分组
- 发送端拥有最老的未确认分组的定时器,定时器到了后重传所有未确认分组
- SR协议
- 发送端最多有N个未确认的已发送分组
- 接收方对每个到来的分组进行分别的确认,只确认在接收窗口的分组
- 发送端为每个未确认的分组保留一个定时器
窗口的最大尺寸
若序号的比特位数为n,即序号从$0$到$2^n-1$ ,那么GBN的发送端窗口最大为$2^n-1$,SR的发送端和接收端窗口最大为$2^{n-1}$
- GBN的窗口如果超过最大限制1个,那么若发送方全部传送且接收方全部接收,但是ACK的返回都超时了,那么会导致发送方重传旧包的各个分组,而此时接收方预期的应该是新的数据包的分组!
- SR的窗口如果超过最大限制1个,那么若出现同上描述的意外情况,那么会导致重传的旧包中包含一个会被接收方认为是新包的一部分的包,那么重复数据会被误认为是新数据
- 再解释一下,就是前面的0和后面的0是不同的数据的分包,他们是不同的数据下的pkg0,但是接收方无法得知发送方的状态,也只会考察发送包的序列号
chp3-5 面向连接的传输 TCP
概述
- 点对点,即发送-接收方
- 可靠服务
- 拥塞控制和流量控制
- 发送和接收缓存
- 全双工数据(同一个练级中数据流双向流动)
- 握手交换彼此状态变量
TCP报文
应用层传数据给传输层时,TCP协议会将数据(TCP将数据看成一个无结构的、有序的字节流)分为若干段,最大报文段大小称为MSS,每个报文段会添加TCP头部,然后向IP网络层传输时添加IP头部,然后再拼接成为连续的数据在链路层传输
- 序号:是原数据流中,每个被TCP分割为报文段的片段头部在数据流中的偏移量,这里不计入TCP头,只讨论TCP要传的数据在未切割时的偏移量
- 确认号:主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号,或者认为是主机A已经成功接收了主机B的 确认号 个字节(0~确认号-1)
上图A已经收到(ACK)了B的前79个字节,同时要发送报文段中从偏移量(Seq)42开始的数据,发送一个字节;于是B返回已收到A的前43字节,同时发送一个开头偏移量为79的数据段给A,同样只有一个字节 - 首部长度:应用层数据从TCP报文段的第几个字节开始
TCP往返时间的估计和超时
往返时间估计公式:$$RTT_{estimate}=(1-\alpha) RTT_{estimate}+\alpha RTT_{newsample},\space \alpha=0.125 \space is \space recommended$$好处是会倾向于移动到近期的值,往前的权重不断下降
RTT偏差(样本RTT和估计RTT的偏移程度)估计公式:
$$RTT_{Dev}=(1-\beta)RTT_{Dev}+\beta|RTT_{sample}-RTT_{estimate}|, \space \beta=0.25 \space is \space recommended$$
超时时间一般为$RTT_{estimate}+4·RTT_{Dev}$,初始超时时间推荐为1秒
可靠数据传输
兼具GBN和SR的特性,具有以下特点:
- 累计确认,只发送当前接收到的最大序列号的ACK
- 单个重传定时器,只为最旧为确认报文段维护定时器
- 超时只重发最旧的未确认报文段
- 是否可以接受乱序?无规范,课程例子认为可以
快速重传:如果发送方收到同一数据的多个冗余ACK(举例:乱序接收中,50未收到,而60、70、80收到并传递3次ACK50),则认为很可能发生了数据丢失,直接重传其中最小序号的段而不用等待定时器
TCP流量控制
接收方应该控制发送方不让发送方发送太多、太快以至于让接收方的缓冲区溢出,因为接收方向上层传递数据的速率受到上层的影响;解决方式就是接收方在返回响应的时候附带一个自身缓冲区空闲空间的信息rwnd,以让发送方调控自己的行为
TCP连接管理
正式交换数据之前需要握手建立连接,包括:同意建立连接、同意连接的双方参数传递(缓冲区等信息)、资源的准备
在一次连接过程中,重复的连接请求并不会导致重复的连接建立,因为seq和ACK的机制可以让这些已经被接收的段被忽略,但是如果重复的连接请求在链接切断之后被发送到接收方,则可能出现问题,也就是2次握手的局限性
服务端会维护一个半连接,这个连接不会接收到来自发送方的任何数据,也就无法收到“连接关闭请求”,这样资源就被占用了,类似僵尸进程
解决方案是 TCP3次握手
第二次握手不仅发出对第一次握手的确认信息,而且也附带着自己的连接建立请求,等待第三次握手的确认信息;这样的好处就是如果发生上面的情况,那么第二次握手发生后,发送端会给接收端发送一个“我没有想跟你建立连接”的拒绝响应,这个半连接就关闭了
关闭连接流程(四次挥手)如下:不是一个可靠的流程,因为不是很确定ACK会不会传送失败
- 客户端先向服务端发送FIN报文,提出其不再主动发送数据,只接受对面传来的FIN以确认关闭
- 服务端接收到客户端的FIN报文,发送ACK告知对面自己已经知晓
- 服务端可以继续向客户端发送内容,最后发送一个FIN给客户端让他关闭
- 客户端接收到FIN,并发送ACK告知服务端自己已经知晓
chp3-6 拥塞控制原理
拥塞非正式定义:太多的数据需要网络传输,超过了网络的处理能力
拥塞的表现:分组丢失(溢出),分组经历比较长的延迟(排队)
上图中实际上吞吐量达到一定程度后,输入和输出就不是线性的了
- 运输数据超过带宽能力导致排队时间延长
- 分组丢失(缓冲区丢弃)或者超时(时间长)会导致发送端重传,重传就意味着输入方输入的数据比输出端本应该输出的更多了,加剧了链路带宽的负担
- 经过多个路由器筛选的数据流本身的输出就比较弱,在和其他数据流竞争有限的路由缓冲区的过程中落入下风,竞争失败被丢弃,导致输出端到丢弃处的运输资源被浪费,因为这些传输没有产生有效的结果,就会导致$\lambda_{out}$接近0
ATM ABR拥塞控制思路
思路是“弹性服务”,若发送端在反馈中得知发送端的路径拥塞了,则会控制发送方的速度,限制在一个最小保障速率上
ATM协议会将数据以信元的方式传输,分为DM数据信元和RM资源管理信元,RM信元间隔插入在数据信元之间;RM通过嵌入到响应端的反馈告知发送端来起到作用,本身不对接收端做任何改变
- NI bit:告知发送端速率不要再增加了(轻微拥塞)
- CI bit:告知发送端路径拥塞了
- ER字段:在整个路径中统计所有路径下的最低带宽
- 数据信元中的EFCI bit:如果被设置为1,则其后面的RM的CI bit被设置为1
chp3-7 TCP拥塞控制
总体策略是检测拥塞的过程只在网络边缘进行判断,减少网络核心的复杂度
拥塞感知
- 拥塞:超时(大概率拥塞导致超时,小概率出错被丢弃导致超时)
- 轻微拥塞:某个段的3个冗余ACK(在有效ACK后又来了3个该段的ACK)
拥塞控制方法
- 维护一个拥塞窗口的值CongWin,其和接收方的RecvWin取min作为实际发送速率
- 超时触发将CongWin设置为1MSS的机制,进入SS阶段,记录Threshold(阈值)为当前CongWin/2作为SS和CA的界限
- 3重复ACK触发将Threshold设置为当前CongWin的一半,CongWin=Threshold+3
- SS阶段CongWin将每隔一个RTT成倍增加,具体的增加方式为每收到一个非冗余ACK增加一个MSS
- CA阶段CongWin每隔一个RTT增加一个MSS,具体为一个非冗余ACK增加1MSS/CongWin
- 一个冗余ACK不对CongWin和Threshold做任何改变
TCP的吞吐量可以简单估计为$throughput=\frac{3}{4}\frac{W}{RTT}$,$W$为Threshold的2倍
TCP流量公平性
K个TCP会话分享一个链路的带宽R,则从长期来看每个会话的有效带宽为R/K
- 假设某时刻处在一个不公平阶段,TCP的拥塞控制机制会对两个TCP连接的流量进行如下图的调整
- UDP不会控制流量,则其会倾向于挤压TCP的共享流量
- 多主机之间可以建立多个TCP连接,TCP连接的流量平均分配但是主机之间的流量取决于TCP连接的数量