传输层
文章目录
概述
-
运输层与网络层的关系
我们用两个家庭通过邮政服务进行通信来类比
假设家庭1:Ann负责家庭内部收发邮件;家庭2:Bill负责家庭内部收发邮件;邮政服务:家庭之间收发邮件
应用层报文 = 信封上的字符 进程 = 家庭中的兄弟姐妹 主机 = 家庭 运输层协议 = Ann和Bill 网络层协议 = 邮政服务
运输层协议能够提供的服务常常受制于网络层协议的服务模型,例如时延和带宽保证,但即使网络层不能提供某些服务,运输层协议也能提供,例如可靠数据传输和数据的安全。
-
因特网运输层概述
UDP和TCP的最基本责任:将主机间IP的交付服务拓展为运行在端系统上的两个进程之间的交付服务;
这种拓展被称为运输层的多路复用与多路分解;
1.多路复用与多路分解
多路分解
将传输层报文段中的数据交付到正确的套接字的工作
多路复用
在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传递到网络层
-
无连接的
UDP套接字由二元组(目的IP地址,目的端口号)标识
-
面向连接的
TCP套接字由二元组(源IP地址,源端口号,目的IP地址,目的端口号)标识
-
Web服务器与TCP
当今的高性能Web服务器通常只使用一个进程,但为每个新的客户连接创建一个具有新连接套接字的线程
2.无连接运输:UDP
UDP的数字段可能会发生数据丢失或不按序递交
无连接的服务:无“握手”;每个segment独立处理
UDP用途:
- 流媒体(可容忍数据丢失但速率敏感)
- DNS
- SNMP 简单网络管理协议
UDP报文段结构
长度字段:UDP报文段中的字节数(首部加数据)
UDP检验和
实现:
发送方的UDP对报文段中的所有16比特字的和进行反码运算,求和时的溢出全部回卷,结果放入校验和字段;接收方将全部16比特字之和的比特位需要全为1。
这提供了差错检测功能,但无法恢复差错
3.可靠数据传输
rdt1.0: reliable channel
经完全可靠信道的可靠数据传输
rdt2.0: channel with bit errors
经具有比特差错信道的可靠数据传输:
-
差错检测:校验和等技术
-
how to recover from errors:
接收方反馈: ACKs && NAKs
重传分组
这里列举的rdt系列是一种停等协议,因为发送方处于等待ACK或NAK的状态时,处于“阻塞”状态,停等行为对性能会有影响,后面的rdt3.0中介绍
缺陷: ACKs / NAKs 也可能出错
rdt2.1:handles garbled ACK/NAKs
遇到出错的ACK或NAK也进行分组重传
但就必须处理重复接收分组(防止重复递交)的问题——解决:给分组增加一位序列号,以区分前后发送的分组
rdt2.2: a NAK-free protocol
rdt2.1可以稍微进行简化,也就是不需要NAK,而是对上次正确接收的分组发送一个ACK(包含所确认的分组序列号)
rdt3.0:channels with errors and loss
approach:发送方等待一个预估的“合理的”时间等待 ACK
需要一个计时器
- 如果是因为分组丢失而超时,则retransmits
- 如果是因为ACK丢失(或仅仅是路由器的延迟)而超时,发送方会retransmits,重复发送了,但2.1版本中解决了重复发送的问题
计时器时间的设定很重要,以保证网络的传输效率。
因为分组序号在0和1之间交替,因此rdt3.0也被称为比特交替协议
-
评价停等行为对性能的影响
e.g.:1 Gbps link, 15 ms prop.delay, 8000 bit packet:
发送方利用率(发送方实际忙于将发送比特送进信道的时间与发送时间之比):
U s e n d e r = L / R R T T + L / R = . 008 30.008 = 0.00027 U_{sender} = \frac{L/R}{RTT+L/R} = \frac{.008}{30.008} = 0.00027 Usender=RTT+L/RL/R=30.008.008=0.00027
有很大的性能问题解决:允许发送方发送多个分组而无需等待确认——流水线可靠数据传输协议
-
必须增加分组序列号范围
-
协议的发送方和接收方两端也许必须缓存多个分组
按照上面两个要求,有两种流水线的rdt协议:
-
回退N步(GBN)
又叫滑动窗口协议,窗口长度N不是无限制的,因为需要进行[流量控制](# 流量控制)
-
选择重传(SR)
接收方也维护一个窗口
比较:
设最大序列号为MAX_SEQ
-
比特交替协议
0 < = 发送窗口 < = 1 0<=发送窗口<=1 0<=发送窗口<=1接收窗口 = 1 接收窗口=1 接收窗口=1
-
GBN协议
0 < = 发送窗口 < = M A X _ S E Q 0<=发送窗口<=MAX\_SEQ 0<=发送窗口<=MAX_SEQ
接收窗口 = 1 接收窗口=1 接收窗口=1
-
SR协议
0 < = 发送窗口 < = ( M A X _ S E Q + 1 ) / 2 0<=发送窗口<=(MAX\_SEQ+1)/2 0<=发送窗口<=(MAX_SEQ+1)/2
接收窗口 = ( M A X _ S E Q + 1 ) / 2 接收窗口=(MAX\_SEQ+1)/2 接收窗口=(MAX_SEQ+1)/2
-
4. 面向连接的运输:TCP
point-to-point
reliable,in-order byte steam
pipelined
full duplex data
connection-oriented
flow controlled
TCP报文结构
TCP把数据看成一个无结构的有序的字节流
-
32比特序列号字段
该报文段首字节的字节流编号
-
32比特确认号字段
TCP是全双工的,主机A向主机B发送数据的同时也接收来自B的数据
主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号
-
16比特接收窗口字段
流量控制,用于指示接收方愿意接受的字节数量
往返时间的估计与超时
方法:指数加权移动平均(EWMA)
推荐值: α = 0.125 \alpha=0.125 α=0.125、 B = 0.25 \Beta=0.25 B=0.25
- 估计RTT:
E
s
t
i
m
a
t
e
d
R
T
T
=
(
1
−
α
)
⋅
E
s
t
i
m
a
t
e
d
R
T
T
+
α
⋅
S
a
m
p
l
e
R
T
T
EstimatedRTT = (1-\alpha)·EstimatedRTT + \alpha·SampleRTT
EstimatedRTT=(1−α)⋅EstimatedRTT+α⋅SampleRTT
2. 测量RTT的偏差:
D
e
v
R
T
T
=
(
1
−
β
)
⋅
D
e
v
R
T
T
+
β
⋅
∣
S
a
m
p
l
e
R
T
T
−
E
s
t
i
m
a
t
e
d
R
T
T
∣
DevRTT = (1-\beta)·DevRTT + \beta·|SampleRTT - EstimatedRTT|
DevRTT=(1−β)⋅DevRTT+β⋅∣SampleRTT−EstimatedRTT∣
3. 设置重传超时间隔:
T i m e o u t I n t e r v a l = E s t i m a t e d R T T + 4 ⋅ D e v R T T TimeoutInterval = EstimatedRTT + 4 · DevRTT TimeoutInterval=EstimatedRTT+4⋅DevRTT
可靠数据传输
-
发送方的高度简化的描述
发送方只用超时来恢复报文段的丢失
/*假设发送方不受TCP流量和拥塞控制的限制,来自上层数据的长度小于MSS,且数据传送只在一个方向进行。*/ NextSeqNum=InitialSeqNumber SendBase=InitialSeqNumber loop (永远) { switch (事件) 事件:从上面应用程序接收到数据e 生成具有序号NextSeqNum的TCP报文段 if (定时器当前没有运行) 启动定时器 向IP传递报文段 NextSeqNum=NextSeqNum + length(data) break; 事件:定时器超时 重传具有最小序号但仍未应答的报文段 启动定时器 break; 事件:收到ACK,具有ACK字段值y if (y > SendBase) { SendBase=y if (当前仍无任何应答报文段) 启动定时器 } break; } /*结束永远循环*/
-
全面的描述
-
超时间隔的翻倍
每一次定时器超时,超时间隔翻倍
这个修改提供一个形式受限的拥塞控制,后面有更复杂的TCP[拥塞控制](# 拥塞控制)形式
-
快速重传
超时触发重传存在的问题:超时周期可能相对较长
解决:使用快速重传,即一旦收到3个冗余ACK,TCP执行快速重传,ACK收到事件处理修改为:
事件:收到ACK,具有ACK字段值y if (y > SendBase) { SendBase=y if (当前仍无任何应答报文段) 启动定时器 ・ } else {/* 对已经确认的报文段的一个冗余ACK */ 对y收到的冗余ACK数加1 if (对y==3收到的冗余ACK数) /* TCP快速重传*/ 重新发送具有序号y的报文段 } break;
-
-
TCP是GBN协议与SR协议的混合体
TCP是采用了累计确认(GBN的特点),但如果由于一组报文段中的某个分组丢失而后续的分组仍能到达,TCP采取的是选择确认和选择重传(SR的特点),即TCP接收方会有选择地确认失序报文段,TCP发送方就可以跳过重传那些已被接收方选择确认过的报文段。
流量控制
流量控制服务是为了消除发送方使接收方缓存溢出的可能性:TCP连接之后,双方都设置了接收缓存(全双工),接收方接受数据后放入接收缓存,相关联的应用进程能够从该缓存中读取数据,但如果读取时相对缓慢,而发送方发送的太多、太快,就容易使得接收缓存溢出。
实现:发送方主机A维护一个变量:接收窗口rwnd,该变量给发送方A一个指示——接收方B还有多少可用的缓存空间。假设接收方B为他们的连接分配了缓存RcvBuffer:
对于接收方B:
r
w
n
d
=
R
c
v
B
u
f
f
e
r
−
[
L
a
s
t
B
y
t
e
R
c
v
d
−
L
a
s
t
B
y
t
e
R
e
a
d
]
rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]
rwnd=RcvBuffer−[LastByteRcvd−LastByteRead]
B将当前rwnd值放入它发给主机A的报文段接收窗口字段中,通知主机A它在该连接的缓存中还有多少可用空间。
发送方通过将未确认的数据量控制在值rwnd以内,可以保证主机A不会使主机B的接收缓存溢出:
L
a
s
t
B
y
t
e
S
e
n
t
−
L
a
s
t
B
y
t
e
A
c
k
e
d
≤
r
w
n
d
LastByteSent - LastByteAcked \leq rwnd
LastByteSent−LastByteAcked≤rwnd
TCP连接管理
-
建立连接:三次握手(three-way handshake)
- 客户:SYN报文段(报文段首部中的SYN比特标识位置为1)
- 服务器:SYNACK报文段(SYN比特置为1)
-
最后报文段:为该连接分配缓存和变量,可以携带数据(STN比特置为0)
-
关闭连接:四次挥手
拥塞控制
- 拥塞的表现
- 当分组的到达速率接近链路容量时,分组经历巨大的排队时延;
- 发送方执行重传甚至执行不必要的重传(遇到大时延时);
- 当一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量被浪费了。
- 通用的拥塞控制方法(根据网络层是否为运输层拥塞控制提供了显示的帮助为区分)
- 端到端拥塞控制(无显示支持)
- 网络辅助的拥塞控制(有显示反馈:路由器直接网络反馈或经由接收方的网络反馈)
TCP拥塞控制
TCP发送方可能因为IP网络的拥塞而被遏制
三个问题:
-
发送方如何限制发送流量的速率?
发送方跟踪一个额外的变量拥塞窗口cwnd
L a s t B y t e S e n t − L a s t B y t e A c k e d ≤ m i n { c w n d , r w n d } LastByteSent - LastByteAcked \leq min\{cwnd, rwnd\} LastByteSent−LastByteAcked≤min{cwnd,rwnd} -
发送方如何感知拥塞?
- 超时
- 收到接收方的3个冗余ACK
-
发送方如何确定发送速率?
大体方向:
- 当丢失报文段时应降低发送速率
- 当对先前未确认报文段的确认到达时,增加发送速率
TCP拥塞控制算法
- 慢启动
- 拥塞避免
- 快速恢复(新版本TCP Reno)