3-传输层
文章目录
本节内容:
-
理解基本理论、基本机制
- 多路复用、多路分用
- 可靠数据传输
- 流量控制
- 拥塞控制
-
掌握Internet传输层协议
- UDP:无连接传输服务
- TCP:面向连接的传输服务
- TCP拥塞控制
3.1-传输层服务
计算机网络MOOC_301_传输层概述.pdf
传输层协议为运行在不同Host上的进程提供了一种逻辑通信机制
逻辑通信机制:两个进程仿佛是连接在一起的,不需要了解传输介质,物理距离,经过多少路由器等
端到端的传输层协议:
-
发送方:将应用递交的消息分层Segments,并向下传输给网络层
-
接收方:将接收方的segments组装成消息,上交给应用层
传输层与网络层区别
-
网络层提供主机之间的逻辑通信机制
-
传输层提供应用进程之间的逻辑通信机制
3.2-多路复用和多路分用
为什么要进行多路复用/多路分用?
如果某层下一个协议直接对应多个协议/实体,那么需要复用/分用
如上图,主机2的P1和P2进程同时与1、3主机建立连接,那么需要正确地交付进程,这时候需要多路分用。
多路分用:传输层依据头部信息将收到的Segment交给正确的Socket,即不同的进程
多路复用:在发送之前为每块数据封装上头部信息,交给网络层。
分用
主机接收IP数据报(datagram)
- 每个数据报携带源IP、目的IP
- 每个数据报携带传输层的段(segment)
- 每个Segment携带源端口号和目的端口号
- 主机接收Segment后,传输层提前IP、端口,将segment导入对应socket
无连接分用
- 利用端口号创建Socket
DatagramSocket mySocket1 = new DatagramSocket(99111);
DatagramSocket mySocket1 = new DatagramSocket(99222);
-
UDP的Socket使用二元组标识(IP+port)
-
主机收到UDP段
- 检查段中目的端口号
- 将UDP段 导向 对应Socket
-
来自不同源的数据包被导向同一个Socket(只要目的IP+端口是一样的)
例:
创建一个6428端口的服务器Socket
面向连接的分用
- TCP的Socket使用四元组标识
- 源IP、端口
- 目的IP、端口
- 接收端创建多个进程,相当于多个Socket用于区分连接
例:
多进程的服务器,假设你不仅在ping服务器,还使用http连接
例:多线程web服务器:
进程创建多个线程,操作系统会自动创建并分配socket
3.3-UDP
UDP: User Datagram Protocol [RFC 768]
特点:
- 基于Internet IP协议
- 能够复用分用
- 简单的错误校验功能(Checksum)
为什么需要在传输层检验:
- 路由器转发过程中也可能出错
- 链路层功能专一一点比较好
Best Effort服务:UDP段可能丢失、不按顺序到达
无连接:
- 不需要建立握手
- 每个报文独立于其他段
UDP优点:
- 延迟少:无需建立连接,eg: DNS
- 实现简单:无需维护连接状态
- 头部开销小(8字节,TCP20字节)
- 没有拥塞控制:上层应用可以更好的控制发送时间
- 可以自己造轮子【doge】
用途:
- 容忍丢失、速率敏感服务,如流媒体
- DNS、SNMP
UDP上实现可靠数据传输
- 应用层增加可靠性机制
- 应用层增加错误恢复机制
UDP校验和
目的:检查UDP段在传输中是否发生错误
发送方计算校验和:
- 将段分成 16-bit * n 个整数
- 计算所有整数的和,进位移动后相加,按位取反,得到校验和
- 将checksum放入对应字段
接收方计算校验和,并对比校验和,如果不相等就丢掉。(相等还有错误的概率比较小)
3.4-可靠数据传输的基本原理
概述
什么是可靠:不错、不丢、不乱
为什么需要可靠数据传输协议(rdt):
- 可靠数据传输对各层都很重要
- 网络Top-10问题
- 信道的不可靠特性决定了可靠数据传输协议的复杂性
服务角度
实现角度
接口
- rdt_send:被上层应用调用,将数据交给rdt以发送给对方
- udt_send:被rdt调用,在不可靠信道上向接收方传输数据(IP协议)
- rdt_rcv:当数据包接收时调用
- deliver_data:被rdt调用,向上层应用交付数据
程序就是状态机
利用状态机(Finite State Machine, FSM)刻画传输协议:
rdt1.0
特点:
- 底层信道完全可靠(理想结构)
- 接收方和发送方的FSM独立
发送方直接发,接收方直接收就行了
rdt2.0
特点:
- 信道会产生位错误
- 差错检验
- ACK/NAK
- 重传
可以使用校验和检测错误
- 确认机制(Acknowledgements, ACK):接收方告诉发送方正确收到
- NAK:接收方告诉发送方数据包发生了错误
- 发送方收到NAK后,重传分组
基于此协议的rdt协议称为ARQ(Automatic Repeat reQuest)协议
发送方每次发送一个数据包都需要等待接收端确认信号,这称为停等协议
缺陷:
- 如果NAK/ACK自己错了怎么办?
rdt2.1
如果NAK/ACK自己错了怎么办?
- 为ACK/NAK增加校验和(如hamming码
- 增加额外的控制消息
- 重传
- 产生重复分组
如何解决重复分组问题?
- 序列号(Sequence Number):发送方给每个分组增加一个序列号
- 接收方丢弃重复分组
rdt2.2
无NAK消息协议:只使用ACK
- 接收方告知最后一个正确分组
- ACK消息中加入正确分组的序列号
- 发送方接收到重复ACK的消息后,相当于收到NAK,重传
rdt3.0
特点:
- 信道可能错误、丢失,校验和也会错误
- 增加定时器
解决方法:发送方等待一段时间,如果没收到反馈,那么重传
性能分析
rdt能正确工作,但性能不好
eg: 1Gbps链路,15ms端到端传播延迟,1KB分组
T
t
r
a
n
s
m
i
t
=
L
R
=
8
k
b
/
p
k
t
1
0
9
b
/
s
e
c
=
8
m
s
T_{transmit} = \frac{L}{R} = \frac{8\ kb/pkt}{10^9\ b/ sec} = 8 ms
Ttransmit=RL=109 b/sec8 kb/pkt=8ms
发送方利用率:发送方发送时间百分比
U
s
e
n
d
e
r
=
L
/
R
R
T
T
+
L
/
R
=
0.00027
U_{sender} = \frac{L / R}{RTT + L/R} = 0.00027
Usender=RTT+L/RL/R=0.00027
即,在1Gbps链路上,每30ms才能发送一个分组,即
33
K
B
/
s
e
c
33\ KB/sec
33 KB/sec, 说明网络协议限制了物理资源的利用
3.5-流水线机制滑动窗口协议
流水线机制:一次发3个,或者一次发5个,可以提高效率
实现流水线协议:
- 更大的序列号范围
- 更大的存储空间用来缓存分组
滑动窗口协议
滑动窗口协议:Sliding-window protocol
窗口:允许使用的序列号范围,尺寸为N,表示最多能等待确认N个消息
滑动窗口:随着协议的运行,窗口在序列号课件向前滑动
GBN
Go-Back_N协议:
发送方:
-
假定序列号有 k-bit,空间 2 n 2^n 2n
-
窗口尺寸N,最多允许N个分组未确认
-
ACK:确认序列号 1-n 的分组均已被正确接收
-
为未确认的分组设置定时器
-
超时:重传序列号大于等于N,还未收到ACK消息
-
发送方扩展FSM
接收方:
- 没有缓存
- ACK:简单发送最高序列号的正确分组的ACK
- 乱序到达的分组:
- 直接丢弃(没有缓存)
- 重新确认整理好最大的、按序到达的分组
eg
练习题
数据链路层采用 GBN 协议,发送方已经发送了编号为0~7的帧。当计时器超时时,若发送方只收到0、2、3号帧的确认,则发送方需要重发的帧数是多少?分别是那几个帧?
解:3号表示0-3号都接收了,4567没有接收,需要重发:4、5、6、7
SR
GBN缺陷:重传时会重传很多数据包,导致不必要的开支
Selective Repeat协议:
- 接收方对每个分组单独确认,设置缓存机制,可以接收乱序到达的分组
- 发送方只重传没收到的ACK分组
- 为每个分组设置定时器
- 发送方窗口:
- N个练习序列号
- 已发送未确认的分组
SR困境
序列号比较小,窗口比较大时,会发生错误,于是我们规定 N S + N R ≤ 2 k N_S+N_R\leq2^k NS+NR≤2k
3.6-TCP
3.6.1-概述
特点:
- 点对点,沿途路由器不会影响连接状态
- 可靠的、按序的字节流
- 流水线机制
- tcp拥塞控制和流量控制机制设置窗口尺寸
- 缓存,连接双方都有缓存
- 全双工:同一连接中能传输双向字节流
- 面向连接
- 通信双方在发送数据之前必须建立连接
- 连接状态只在两端维护
- 连接包括:双方主机缓存、连接状态变量、Socket
- 流量控制机制
TCP段结构
序列号:segment中第一个字节编号,建立TCP连接时,双方随机选择序列号
ACKs:希望收到的下一个字节的序列号,
累计确认:该序列号之前的所有字节均被正确接收
TCP规范中没有规定如何处理乱序到达的Segment,需要自己实现,(手动@cs144)
3.6.2-TCP可靠数据传输
RTT和超时
设置定时器和超时时间:稍大于RTT。避免不必要的重传和丢失时反应过慢。
估计RTT:
SampleRTT: 测量从段发出到收到ACK的时间
ExtimatedRTT: 测量多个RTT,求平均值
R
T
T
E
s
t
i
m
a
t
e
d
=
(
1
−
α
)
∗
R
T
T
E
s
t
i
m
a
t
e
d
+
α
∗
R
T
T
S
a
m
p
l
e
{RTT}_{Estimated} = (1-\alpha)*{RTT}_{Estimated} + \alpha*{RTT}_{Sample}
RTTEstimated=(1−α)∗RTTEstimated+α∗RTTSample
超时时间 =
R
T
T
E
s
t
i
m
a
t
e
d
+
安全边界
{RTT}_{Estimated} + 安全边界
RTTEstimated+安全边界
RTT变化大,边界就变大
测量RTT变化值:
R
T
T
d
e
v
=
(
1
−
β
)
∗
R
T
T
D
e
v
+
β
∗
∣
R
T
T
S
a
m
p
l
e
−
R
T
T
E
s
t
i
m
a
t
e
d
∣
{RTT}_{dev} = (1-\beta)*{RTT}_{Dev} + \beta * |{RTT}_{Sample} - {RTT}_{Estimated}|
RTTdev=(1−β)∗RTTDev+β∗∣RTTSample−RTTEstimated∣
一般
β
=
0.25
\beta = 0.25
β=0.25
超时时间:
T
i
m
e
o
u
t
I
n
t
e
r
v
a
l
=
R
T
T
E
s
t
i
m
a
t
e
d
+
4
∗
R
T
T
D
E
V
TimeoutInterval = {RTT}_{Estimated} + 4*{RTT}_{DEV}
TimeoutInterval=RTTEstimated+4∗RTTDEV
发送方事件
- 从应用层收到数据
- 创建Segment
- 序列号
- 开启定时器
- 设置超时时间
- 超时
- 重传引起超时的Segment
- 重启定时器
- 收到ACK
- 确认此前未确认的Segment
- 更新SendBase
- 如果窗口还有未确认的分组,重启定时器
TCP重传示例
快速重传机制
如果Sender收到对同一数据的3个ACK后,会假定该数据之后的段丢失,Sender会在定时器超时之前进行重传
3.6.3-TCP流量控制
流量控制:发送方不会发太多,避免淹没接收端
Buffer中可用空间
= RecvWIndow
= RecvBuffer - [LastByteRecv - LastByteRead]
接收方在头部字段将RecvWindow告知发送方,发送方限制自己已发送未ACK数据量不超过RecvWindow尺寸。
如果RecvWindow = 0,发送方会发送很小的字段,避免死锁。
3.6.4-TCP连接管理
TCP传输数据之前需要建立连接
- 初始化TCP变量
- Client:连接发起者
- Server:等待用户连接请求
三次握手:
- SYN:客户机向服务器发送SYN段
- SYNACK:服务器收到SYN,答复SYNACK段,服务器分配缓存,告知客户端
- ACK:客户端收到SYNACK,反馈ACK段,可能包含数据
3.7-拥塞控制原理
网络Top-10问题之一
拥塞(Congestion):发送主机太多以至于网络无 法处理,表现为路由器缓存溢出导致的分组丢失,以及路由器缓存排队导致的分组延迟过大
3.7.1-拥塞的成因
场景1-无限缓存
假设有两个Sender和两个Receiver,一个无限缓存的路由器
因为无限缓存,分组不会丢失,此时没有重传。
吞吐率随着 λ i n \lambda_{in} λin增大, λ o u t \lambda_{out} λout线性增长,直到达到最大throughput: c 2 \frac{c}{2} 2c
随着路由器中缓存增多,时延增长,快接近 c 2 \frac{c}{2} 2c时,时延快速增长
场景2-缓存有限
此场景路由器有有限的buffer,Sender会重传分组
λ i n ′ \lambda^{\prime}_{in} λin′表示重传的数据
- 情况a:Sender能够获知路由器buffer信息,空闲时才发, λ i n = λ o u t \lambda_{in} = \lambda_{out} λin=λout(理想goodput)
- 情况b:丢失后重发 λ i n ′ > λ o u t \lambda_{in}^{\prime} > \lambda_{out} λin′>λout
- 情况c:分组丢失或定时器超时后重发, λ i n ′ \lambda_{in}^{\prime} λin′变得更大,有效传输更低
多跳网络
分组丢失时位于传输上游的所有传输都被浪费
3.7.2-拥塞的方法
端到端拥塞控制:
- 网络层不需要显式地提供支持
- 端系统通过观察loss、delay判断拥塞
- TCP采用
网络辅助控制:
- 路由器反馈网络拥塞信息
- 简单的拥塞指示
ATM ABR拥塞控制
ABR:available bit rate
- 弹性服务
- 如果发送方路径 underloaded,使用可用带宽
- 如果发送方路径拥塞,将发送速率降到最低
RM:resource management cells
- 交换机设置RM cell位(网络辅助)
- NI:rate 不允许增长
- CI:拥塞指示
- RM cell 由接收方返回给发送方
- ER:速率字段
- 拥塞交换机将ER设置得更低
- 发送方获知路径支持最低速率
- EFCI:拥塞交换机将其设为1
- 若RM cell前面的data cell的EFCI,那么发送方在返回的RM cell中置为CI
3.8-TCP拥塞控制
Sender限制发送速率:
拥塞变量:CongWIn >= LastByteSent - LastByteActed
$rate = \frac{CongWin}{RTT} $Bytes/Sec
感知网络拥塞:
Loss事件 = timeout 或者 3个重复ACK
发生 loss事件后发送方降低速率,加性增,乘性减(AIMD)
AIMD:逐渐增加发送速率,谨慎检测可用带宽,直到发送loss
慢启动SlowStart
TCP建立时指数性增长,避免浪费网络资源
初始速率虽然很慢,但是攀升速度快
Threshold变量
用来将指数增长转变为线性增长
当CongWin得到Loss事件前值一半时设置为其一半
以上方法比较保守,之后映入Series Reno变量
Loss事件处理
3个重复ACK:COngWin减半,线性增长
Timeout:CongWin设为1个MSS,指数增长直到达到Threshold
TCP拥塞控制算法
源码:https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_cong.c