第3章:传输层
1 传输服务和协议
传输层为运行在不同主机上的应用进程提供逻辑通信
传输协议运行在端系统
发送方:将报文拆分成报文段,交给网络层
接收方:将报文段合并为报文,交给应用
协议可选择TCP和UDP
TCP:可靠的保序的传输
多路复用,解复用
流量控制
拥塞控制
面向连接
UDP:不可靠,不保序的传输
多路复用,解复用
没有为IP服务添加更多的额外服务
都不提供时延和带宽保证的服务
2 多路复用和解复用
在发送方主机多路复用:
从多个套接字接收多个进程的报文,根据套接字对应的IP地址和端口等信息对报文段用头部加以封装(该头部信息用于以后的解复用)
在接受方解复用
根据报文段中的IP和端口信息将收到的报文段交给正确的套接字和对应的应用进程
多路解复用工作原理
解复用作用:TCP或UDP实体根据某些信息,把报文段的数据部分交给正确的socket,从而交给正确的进程
主机收到IP数据报
每个数据报中包含源IP和目标IP
每个数据报中包含一个数据段
数据段有源端口和目标端口
主机联合使用IP和端口将报文发给合适的套接字
3 无连接传输 UDP
UDP特性
尽力而为的服务,报文段
可能丢失
可能乱序
无连接:
UDP发送端和接收端之间没有握手
每个UDP报文都被独立处理
UDP被用于:
流媒体
DNS
SNMP
在UDP上实现可靠传输
在应用层增加可靠性
应用特定的差错恢复
UDP:用户数据报协议
为什么需要UDP?
不建立连接(会增加延时)
简单:发送方和接收方没有连接状态
报文段头部很小
无拥塞控制和流量控制:可以尽可能快的发送报文段
![[第3章:传输层_time_1.png]]
UDP校验和
目标:检测在被传输报文段中的差错
发送方:
将报文段的内容视为16比特的整数
校验和:报文段的加法和(1的补运算)
发送方将校验和放在UDP的校验和字段
接受方:
计算接收到的报文段的校验和
判断是否和报文段中的校验和一致
4 可靠数据传输的原理
信道的不可靠特点决定了可靠数据传输协议(rdt)的复杂性
使用有限状态机(FSM)来描述发送方和接收方
状态:在该状态时,下一个状态只由下一个事件唯一确定
![[第3章:传输层_time_2.png]]
Rdt1.0:在可靠信道上的可靠数据传输
![[第3章:传输层_time_3.png]]
Rdt2.0:具有比特差错的信道
下层信道可能会出错:将分组中的比特反转
用校验和来检测比特差错
问题:怎样从差错中恢复
确认(ACK):接收方显式的告诉发送方分组已被正确接收
否定确认(NACK):接收方显式告诉发送方分组出现了差错
发送方接收到NACK后重传分组
rdt2.0新机制:采用差错控制编码进行差错检测
发送方差错控制编码,缓存
接收方使用编码捡错
接收方的反馈:控制报文(ACK,NACK)
发送方收到反馈相应的动作
![[第3章:传输层_time_4.png]]
rdt2.1 :ACK/NACK出错
接收方发送的确认信号出错,导致发送方不知道具体信号
引入新的机制:序号
发送方在每个分组中加入序号
如果ACK/NACK出错则发送方重传当前分组
接收方丢弃重复分组,重新给信号
停等协议: 发送方发送一个分组,然后等待接收方的应答
![[第3章:传输层_time_5.png]]
rdt2.2 : 无NACK的协议
功能同rdt2.1,但只使用ACK
接收方对最后正确接收的分组发ACK,以代替NAK
接收方必须显式的包含正确接收分组的序号
当收到重复的ACK时,发送方与收到NAK一样的动作:重传当前分组
为后面的一次发送多个数据单位做一个准备
一次能发送多个
每一个的应答都有两个状态比较麻烦,不使用NAK确认信息减少一半,协议处理简单
![[第3章:传输层_time_6.png]]
rdt3.0: 具有比特差错和分组丢失的信道
方法:发送方等待ACK一段合理的时间
发送方超时重传
问题:如果分组或ACK只是延时了
重传会导致数据重复,但可以利用序列号解决这个问题
接收方必须正确指明接收的序列号
需要一个倒计时定时器
![[第3章:传输层_time_7.png]]
在链路容量比较大的情况下,性能很差
![[第3章:传输层_time_8.png]]
流水线协议
流水线:允许在发送方未得到对方确认的情况下一次发送多个分组
必须增加序号的范围:用多个bit表示分组的序号
在发送方/接收方要有缓冲区
两种通用的流水线协议:回退N步(GBN)和选择重传(SR)
发送缓冲区:
形式:内存中的一个区域,落入缓冲区的分组可以发送
功能:用于存放已经发送但没有得到确认的分组
必要性:需要重发时可用
发送缓冲区的大小:一次最多可以发送多少个未经确认的分组
停止等待=1
流水线协议>1,不能过大,链路利用率不能超100%
发送缓冲区中的分组
未发送的:落入发送缓冲区的分组,可以连续发送出去
已经发送出去的,等待对方确认的分组:发送缓冲区的分组只有得到确认才能剔除
滑动窗口协议-slide-window
发送窗口:发送缓冲区内容的一个范围
那些已发送但未得到确认分组的序号构成的空间
发送窗口的最大值<=发送缓冲区的值
一开始:没有发送任何一个分组
后沿=前沿
之间为发送窗口的尺寸=0
每发送一个分组,前沿前移一个单位
发送窗口的极限不能超过发送缓冲区
发送窗口后沿移动
条件:老分组得到确认
结果:发送缓冲区落入新的分组,来了分组可以发送
移动的极限:不能超过前沿
接收窗口
接收窗口=接收缓冲区
接收窗口用于控制那些分组可以接收
只有收到的分组序列号落入接收窗口内才允许接收
如序号在接收窗口之外则丢弃
接收窗口=1,则只能顺序接收
接收窗口>1,则可以乱序接收
但提交接收窗口之内的分组要按顺序
正常情况下两个窗口的互动
发送窗口:
有新分组落入发送缓冲区范围,发送->前沿移动
来了老的低序列号的确认->后沿向前移动->新的分组可以落入发送缓冲区的范围
接收窗口:
收到分组,落入接收缓冲窗口范围内,接收
是低序列号,发送确认给对方
异常情况下GBN的2窗口互动
发送窗口:
新分组落入发送缓冲区范围,发送->前沿移动
超时重传机制让发送窗口内的所有分组重新发送
来了老分组的重复确认->后沿不向前移动->新的分组无法落入发送缓冲区的范围
接收窗口:
收到乱序分组,没有落入到接收窗口范围内,丢弃
(重复)发送老分组的确认,累计确认
异常情况下SR的2窗口互动
发送窗口:
新分组落入发送缓冲区范围,前沿向前移动
收到乱序分组的确认,后沿无法向前移动,前沿无法移动,有新的分组无法落入到发送缓冲区访问
每个分组维护一个超时计时器,哪个分组超时就重发哪个分组
接收窗口:
收到乱序分组,落入到接收缓冲区的范围内,接收
单独发送该分组的确认
GBN协议和SR协议的异同
相同:
发送窗口>1
一次性可以发送多个分组
不同:
GBN的接收窗口=1
接收端:只能按顺序接收
发送端:从表现来看,一旦一个分组没有发送成功,这个分组后的所有分组都要重新发送
SR的接收窗口>1
接收端可以乱序接收
发送端可以只重传未确认或超时的分组
![[第3章:传输层_time_9.png]]
5 TCP协议
TCP特点
点对点:
一个发送方一个接收方
可靠的、按顺序的字节流:
没有报文边界
管道化(流水线):
TCP拥塞控制和流量控制设置窗口大小
全双工数据:
在同一连接中数据双向流动
MSS:最大报文段大小
面向连接:
在数据交换之前,通过握手(交换控制报文)初始化发送方、接收方的状态变量
有流量控制:
发送方不会淹没接收方
5.1 TCP报文段结构
![[第3章:传输层_time_10.png]]
序号:指的是载核的第一个字节在整个字节流中的偏移量
确认号:如果ACK=555,则意味着接收方已经收到了554个字节
TCP往返延时和超时
怎么设置TCP的超时?
比RTT要长,但RTT是变化的
太短:太早重传,无意义
太长:对报文段丢失反应太慢
怎么估计RTT?
sampleRTT:测量报文段从发送到收到确认的时间
如果有重传,忽略此次测量
sampleRTT会变化,因此估计的RTT应该比较平滑
对最近几个测量做平均值
![[第3章:传输层_time_11.png]]
![[第3章:传输层_time_12.png]]
5.2 TCP如何做RDT
TCP在IP不可靠服务的情况下建立了rdt
管道化的报文段
GBN or SR
累计确认(GBN)
单个重传定时器(GBN)
是否可以乱序接收,没有规范,可以丢弃也可以缓存
通过以下事件触发重传
超时(只重发那个最早未确认的段:SR)
重复的确认
TCP ACK产生的建议
所期望的序列号的报文段按序到达。所有在期望序列号之前的数据都已经被确认
延迟的ACK,对另一个报文段的到达最多等待500ms。如果下一个报文段在这个时间间隔内没有到达则发送一个ACK
有期望序号的报文段到达,另一个按序报文段等待发送ACK
立即发送单个累计ACK,以确认两个按序报文段
比期望序列号大的报文段乱序到达,检测出数据流中的间隔
立即发送重复ACK,指明下一个期待字节的序号
能部分或完全填充接收数据间隔的报文段到达
若该报文段起始于间隔的低端,则立即发送ACK
快速重传
超时周期往往太长:在重传丢失报文段之前的延时太长
通过重复的ACK来检测报文丢失
发送方通常发送大量的报文段
如果报文段丢失会引起多个重复的ACK
如果发送方收到同一数据的3个冗余ACK,重传最小序号的段:
快速重传:在定时器过时之前重发报文段
5.3 流量控制
接收方控制发送方,不让发送方发送太多、太快以至于让接收方的缓存溢出
接收方在向发送方的TCP段头部的rwnd字段通告其空闲buffer大小
RcvBuffer大小通过socket选项设置,通常默认为4096个字节
很多操作系统自动调整rcvBuffer
发送方限制未确认的字节个数<=接收方发送过来的rwnd值,保证接收方不会被淹没
缓存中可用空间(假设TCP接收方丢弃乱序的报文段)= RcvWindow = RcvBuffer - 【LastByteRcvd - LastByteRead】
处理“零窗口”死锁:如果接收方缓存已满,它会通告一个
rwnd = 0,这称为零窗口(Zero Window),发送方必须暂停发送。但如果之后接收方缓存有空余,重新通告的非零窗口报文丢失了,双方就会陷入“死等”。为解决这个问题,TCP引入了持续计时器(Persistence Timer)。当发送方收到零窗口通知后,会启动此计时器。超时后,发送方会发送一个**零窗口探测(Zero Window Probe)** 报文(通常只含1字节数据),接收方在回应此探测报文时,会再次告知当前窗口大小,从而打破僵局
5.4 连接管理
在正式交换数据之前,发送方和接收方建立通信关系:
同意连接(每一方都知道对方愿意建立连接)
同意连接参数初始化,资源初始化
![[第3章:传输层_time_13.png]]
连接释放
客户端,服务端分别关闭它这一侧的连接
发送FIN=1的报文段
一旦收到FIN,使用ACK回应
接收到FIN段,ACK可以和它发出的FIN段一起发送
可以处理同时的FIN交换
对称释放并不完美,两军问题
5.5 拥塞控制
拥塞:
非正式的定义:太多的数据需要网络传输,超过了网络的处理能力
与流量控制不同,拥塞的表现:
分组丢失(路由器缓冲区溢出)
分组经历较长的延迟(在路由器的队列中排队)
拥塞的代价
为了达到一个有效输出,网络需要作更多的工作(重传)
没有必要的重传,链路中包括了多个分组的拷贝
是那些没有丢失,经历的时间比较长(拥塞状态)但是超时的分组
降低了"goodput"
当分组丢失,任何关于这个分组的上游传输能力都被浪费了
拥塞控制方法
端到端拥塞控制:
没有来自网络的显示反馈
端系统根据延迟和丢失事件判断是否有拥塞
TCP采用的方法
网络辅助的拥塞控制:
路由器提供给端系统以反馈信息
单个bit置位,显示有拥塞
显式提供发送端可以采用的速率
5.6 TCP拥塞控制
TCP拥塞控制:机制
端到端的拥塞控制机制
路由器不向主机反馈有关拥塞的信息
路由器的负担比较轻
符合网络核心简单的TCP/IP架构原则
端系统根据自身得到的信息判断是否拥塞从而采取动作
拥塞控制的几个问题
如何检测拥塞:
轻微拥塞
拥塞
控制策略
在拥塞时如何采用动作降低速率
在拥塞缓解时如何采用动作增加速率
拥塞感知
某个段超时了(丢失事件):拥塞
超时时间到,某个段的确认没有来
原因1:网络拥塞(某个路由器的缓存满了被丢弃)概率大
原因2:分组的差错检查没有通过被丢弃,概率下
一旦超时,就认为拥塞了,有一定误判,但是总体控制方向是对的
有关某个段的3次重复ACK:轻微拥塞
段的第一个ACK:正常,确认绿段,等待红段
段的第二个重复ACK:意味着红段的后一段收到了,蓝段乱序到达
段
速率控制
维持一个拥塞窗口的值:CongWin
发送端限制已发送但未确认的数据量:
LastByteSent - LastByteAcked <= CongWin
从而粗略的控制发送方往网络中注入的速率
Rate = CongWin/RTT bytes/sec
CongWin是动态的,是感知到的网络拥塞程度的函数
超时或3个重复ack:Congwin下降
超时时:CongWin降为1MSS,进入ss节点然后再倍增到CongWin/2(每个RTT),从而进入CA阶段
3个重复的ACK:CongWin降为CongWin/2,进入CA阶段
否则(正常收到ACK,没有发生以上情况):CongWin上升
SS阶段:加倍增加(每RTT)
CA阶段:线性增加(每RTT)
联合控制的方法
发送端控制发送未确认的量同时也不能超过接收窗口,满足流量控制要求
sendwin = min(CongWin,recvwin)
同时满足拥塞控制和流量控制
拥塞控制策略:
慢启动
AIMD:线性增,乘性减
超时时间后的保守策略
5.6.1 TCP慢启动
连接刚建立,CongWin = 1 MSS
如 MSS = 1460 bytes & RTT = 200 msec
初始速率 = 58.4kbps
可用带宽可能 >> MSS/RTT
应该尽可能加速,达到希望的速率
当连接开始时,指数性增加发送速率,直到发生丢失的事件
初始的速率很慢,但是增加速度很快
慢启动过程
当连接开始时,指数性增加发送速率直到发生丢失事件
每一个RTT,CongWin加倍
慢启动阶段:只要不超时或3个重复ACK,一个RTT,CongWin加倍
总结:初始速率很慢,但是加速很快,从长期来看可以忽略
5.6.2 AIMD
MD:Multiplicative Decrease
丢失事件后将CongWin降为1,将CongWin/2作为阈值,进入慢启动阶段(倍增直到CongWin/2)
AI:Additive Increase
当CongWin > 阈值时,一个RTT如没有发生丢失事件,将CongWin加1MSS:探测
实现
变量:Threshold
出现丢失,Threshold设置成CongWin的一半
5.6.3 总结
当CongWin < Threshold , 发送端处于慢启动阶段,窗口指数增加
当CongWin > Threshold,发送端处于拥塞避免节点(congestion-avoidance),窗口线性增长
当收到三个重复的ACK,Threshold设置为CongWin的一半,CongWin变为Threshold + 3
当发生超时事件,CongWin设置为1MSS,Threshold设置为CongWin/2,进入ss阶段
以前没有收到ACK的data被ACKed (正常收到新确认)
慢启动 (SS)
CongWin = CongWin + MSS
如果 CongWin > Threshold(阈值),则状态变为“拥塞避免”(CA)
指数增长 每一个RTT(往返时间),CongWin翻倍,快速探测可用带宽。
以前没有收到ACK的data被ACKed (正常收到新确认)
拥塞避免 (CA)
CongWin = CongWin + MSS * (MSS / CongWin)
加性增长 每一个RTT,CongWin只增加 1 个MSS,缓慢线性增加,趋于稳定。
通过收到3个重复的ACK,发现丢失的事件 (快速重传)
SS 或 CA
Threshold = CongWin / 2
CongWin = Threshold + 3
状态变为“CA”
乘性减 网络出现拥塞,但情况不严重。CongWin减半,但不重置为1,进入拥塞避免阶段。
超时
SS 或 CA
Threshold = CongWin / 2
CongWin = 1 MSS
状态变为“SS”
网络拥塞严重 认为有报文丢失,将CongWin重置为1,重新开始慢启动过程。
重复的ACK
SS 或 CA
对被确认的报文段,增加重复ACK的计数
中间状态 CongWin和阈值(Threshold)保持不变,等待后续事件(如满3个ACK触发快速重传)。
5.7 TCP吞吐量
**TCP的平均吞吐量是多少,使用窗口window尺寸W和RTT来描述?
○ 忽略慢启动阶段,假设发送端总有数据传输
□ W: 发生丢失事件时的窗口尺寸(单位:字节)
○ 平均窗口尺寸(#in-flight字节):3/4 W
○ 平均吞吐量:RTT时间吞吐3/4 W
○ 平均TCP吞吐量 = (3/4 W) / RTT
![[第3章:传输层_time_14.png]]
5.8 TCP的公平性
公平性目标:如果k个连接共享一个带宽为R的瓶颈,每一个会话的有效带宽为R/K。
![[第3章:传输层_time_15.png]]
公平性和UDP
□ 多媒体应用通常不是用TCP
● 应用发送的数据速率希望不受拥塞控制的节制
□ 使用UDP:
● 音视频应用泵出数据的速率是恒定的,忽略数据的丢失
□ 研究领域: TCP友好性
公平性和并行TCP连接
□ 2个主机间可以打开多个并行的TCP连接
□ Web浏览器
□ 例如: 带宽为R的链路支持了9个连接;
如果新的应用要求建1个TCP连接,获得带宽 R/10
如果新的应用要求建11个TCP连接,获得带宽 R/2
最后更新于