一、概述和传输层服务
传输层和网络层的关系
- 网络层
- 主机之间的逻辑通信。
- 传输层
- 进程之间的逻辑通信。
Internet传输层概述
- 发送方
- 传递一个应用层消息;
- 确定报文段头部值;
- 创建报文段;
- 传递报文段到网络层。
- 接收方
- 从网络层接收报文段;
- 检查头部值;
- 提取应用层消息;
- 通过套接字多路分解消息到应用层。
TCP
- 可靠的、按序的交付
- 提供流量控制
- 提供拥塞控制
- 需要连接建立
UDP
- 不可靠、不按序交付
- 尽力而为
- 传输层不提供
- 时延保证
- 带宽保证
二、多路复用与多路分解
- 发送主机多路复用
- 从多个套接字收集数据,用首部封装数据,然后将报文段传递到网络层。
- 接收主机多路分解
- 使用头部信息将接收到的报文段传递到正确的套接字。
多路分解如何工作
- 主机接收
IP
数据报- 每个数据报有源、目的
IP
和Port
(指明了套接字)。 - 每个数据搬运一个传输层报文段。
- 每个数据报有源、目的
无连接多路分解
- 发送
UDP
套接字时需指定- 目的
IP
- 目的
Port
- 目的
- 接收
UDP
套接字时需要- 检查报文段中的目的端口号
- 用端口号指示
UDP
报文段属于哪个套接字
面向连接的多路分解
- 接收主机使用这四个值来将报文段定位到适合的套接字
- 源
IP
- 源
Port
- 目的
IP
- 目的
Port
- 源
- 每个连接的用户都有不同的套接字。
总结
- 多路复用/多路分解发生在所有层。
Q:为什么TCP用四元组,而UDP只要二元组?
A:
UDP
套接字仍需要传送自己的源IP
和端口给对方,否则对方无法回应请求。- 使用
UDP
传输,不用考虑分组是从哪个客户端来的,所有请求都在同一个套接字处理。 - 用二元组是因为
UDP
无连接,接收方无需区分发送方。
三、无连接运输:UDP(不考)
- 尽力而为
- 可能丢失
- 将失序的报文交付到应用程序
- 无连接
- 每个
UDP
段都独立于其他段
- 每个
- 为什么有
UDP
- 不需要建立连接
- 简单
- 报文段首部小
- 没有/不需要拥塞控制
UDP报文结构
- 首部开销小
8
字节
- 发送方动作
- 传递应用层消息
- 确定
UDP
头部字段值 - 创建
UDP
报文段 - 传递报文段给
IP
- 接收方动作
- 接收数据报
- 检查
UDP
头部校验和 - 提取应用层消息
- 通过套接字多路分解到应用程序
- 首部格式
UDP校验和
-
发送方
- 将数据看成
16bit
的整数序列 - 校验和
- 数据段内容相加
- 溢出后在末尾加一
- 最后求反码
- 发送者将校验和值放入
UDP
的校验和域。
- 将数据看成
-
接收方
- 计算接收到数据段的校验和
- 检查
-
例子
-
伪首部
- 为了计算校验和
- 为了计算校验和
Q:为什么UDP校验和要算和的反码?
A:
- 接收者可以直接将所有
16bit
数据段和校验和一起加起来检验,最后判断是否为全1
,简单高效。
四、可靠数据传输原理
构造可靠数据传输协议
版本 | 特点 |
---|---|
rdt1.0 | 假设信道是完全可靠的 |
rdt2.0 | 增加了ACK和NAK |
rdt2.1 | 对NAK进行编号 |
rdt2.2 | 用冗余ACK代替NAK |
rdt3.0 | 增加了定时器 |
流水线可靠数据传输协议
- 流水线
- 允许发送多个、传输中的、没有确认的报文。
- 序号数目范围增加
- 双方必须有缓冲区
- 两个通用形式
Go-Back-N
- 选择性重传
回退N步
发送方
- 窗口大小为
N
,允许连续未被确认的分组进行传输。 - 分组头部需要
k
比特表示窗口大小。 - 累积确认
cumulative ACK
ACK(n)
:确认收到n
之前的分组。- 接收到
ACK(n)
:移动窗口到n+1
。
- 对第一个传输出去的分组设置定时器。
接收方
- 总是为正确接收最高序号的分组发送
ACK
。- 可能产生重复的
ACK
- 只需要记住最早还没确认的位置。
- 可能产生重复的
使用技术
- 序号
- 累积确认
- 校验和
- 定时器
- 重传
选择性重传
接收方
- 分别确认所有正确接收的分组
- 缓存分组
- 最后按序上传
- 分组在
[rcvbase, rcvbase+N-1]
- 发送
ACK(n)
- 失序:缓存
- 有序:上传并滑动窗口
- 发送
- 分组在
[rcvbase-N,rcvbase-1]
- 说明该分组为重复分组
- 发送
ACK(n)
发送方
- 分别重传没有收到确认
ACK
的分组- 对每一个没有确认的分组都维持一个定时器。
- 发送窗口
N
个连续的序号- 限制已发送但未确认的分组数量
ACK(n)
在[sendbase,sendbase+N]
- 标记分组
n
被接收 - 如果
n
是最小的未确认分组,则滑动窗口。
- 标记分组
Q:序号空间和窗口长度的关系是什么?
A:
- 窗口长度小于等于序号空间的一半。
使用技术
- 序号
- 逐个确认
- 校验和
- 定时器
- 重传(选择性)
五、面向连接的传输:TCP
TCP连接
- 点到点
- 可靠、有序的字节流
- 全双工数据
- 同一个连接上有双向数据流。
MSS
(maximum segment size
)最大段长度- 应用层报文最大大小,默认
1460
字节。
- 应用层报文最大大小,默认
MTU
(maximum transmit unit
)最大传输单元- 网络层报文最大大小,默认
1500
字节。
M S S = M T U − l e n g t h T C P h e a d e r − l e n g t h I P h e a d e r = M T U − 20 − 20 MSS=MTU-length_{TCP\ header}-length_{IP\ header}=MTU-20-20 MSS=MTU−lengthTCP header−lengthIP header=MTU−20−20
- 网络层报文最大大小,默认
- 累积确认
- 流水线
- 拥塞和流量控制时,设置滑动窗口大小。
- 面向连接
- 数据交换前,初始化发送方与接收方状态,进行握手(交换控制信息)。
- 流量控制
- 发送方不能淹没接收方。
TCP报文长度
-
序号(
Seq
)- 报文段中第一个字节在字节流中的位置编号。
-
确认号(
ACK
)- 期望从对方收到的下一个字节的序号
- 累积确认
A C K = S e q + l e n ( m e s s a g e ) S e q = A C K ACK=Seq+len(message)\\Seq=ACK ACK=Seq+len(message)Seq=ACK
-
TCP
首部是变长的,所以有首部长度字段。UDP
首部固定,就没有这个字段。
往返时间(RTT)的估计与超时
SampleRTT
- 从发送报文段到接收到
ACK
的测量时间(忽略重传)。 - 取最近的多次测量平均,不仅仅是当前
SampleRTT
。 - 会变化,但希望估计出来的
RTT
比较平滑。
- 从发送报文段到接收到
- 指数加权移动平均(
EWMA
)
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 - 超时间隔=估计
RTT
+安全余量
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 - 安全余量
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∣
可靠数据传输
- 流水线发送报文段
- 考虑早期丢失ACK的累积确认
- 使用单个重传计时器
- 重传触发事件
- 超时
- 重复
- 三个主要事件
- 从应用程序接收数据
- 超时
- 收到
ACK
- 快速重传
- 收到重复的
ACK
,直接发送具有最小序号的未确认的报文段。
- 收到重复的
流量控制
- 接收方控制发送方
- 使得发送方不会发得太多太快,导致接收方缓冲区溢出。
- 在
TCP
头部加入了rwnd
,通告其接收缓冲区剩余空间。
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)
TCP连接管理(不考)
建立连接——3次握手
- 发送方/接收方在进行数据交换之前,需先进行握手 :
- 同意建立连接(彼此知道对方愿意建立连接)
- 同意连接参数(例如,初始序号
seq #
, 接收缓冲区大小rcvBuffer
)
关闭连接——4次挥手
六、拥塞控制原理(不考)
拥塞原因与代价
- 拥塞原因
- 太多的源发送太多太快的数据,使网络来不及处理。
- 拥塞表现
- 丢包(路由器缓冲区溢出)
- 时延长(路由器缓冲区中排队)
拥塞控制方法
- 端到端的拥塞控制
- 不从网络中得到明确的反馈。
- 从端系统根据观察到的时延和丢失现象推断出拥塞。
- 网络辅助拥塞控制
- 路由器利用数据流通过拥塞的路由器,向发送/接收主机提供直接反馈。
- 可以指示拥塞级别或明确设置发送速率。
- 指示发送方按照一定速率发送。
七、TCP拥塞控制
拥塞控制:AIMD
- 方法
- 发送方增加发送速率,直到丢包(拥塞)发生,然后在发生丢包事件时降低发送速率。
- 发送方增加发送速率,直到丢包(拥塞)发生,然后在发生丢包事件时降低发送速率。
- 乘性减 (
Multiplicative decrease
) 的发送速率- 检测到
3
个重复ACK
,减半 (TCP Reno
) - 由于超时而发生丢包,降低到
1 MSS
(maximum segment size
) (TCP Tahoe
)
- 检测到
拥塞控制:详情
TCP
发送动作- 发送
cwnd
字节,在RTT
时间内等待ACKs
,然后发送更多的字节。
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 ≤ c w n d LastByteSent – LastByteAcked ≤ cwnd LastByteSent–LastByteAcked≤cwnd
- 发送
拥塞控制:三阶段
慢启动
- 当连接开始的时候,以指数速率增加发送速率,直到第
1
次报文丢失事件发生为止。- 初始 c w n d = 1 M S S cwnd=1\ MSS cwnd=1 MSS
- 每经过一个
RTT
,cwnd
翻倍。 - 每收到一个
ACK
,增加cwnd
。
初始速率很低,但以指数快地增加!
拥塞避免
- 当
cwnd
达到阈值ssthresh
(若超过,则cwnd
取值ssthresh
),就从慢启动(指数增长)变为线性增长。ssthresh
在丢包之后,变为cwnd
的一半。
快速恢复
- 收到
3
个重复ACK
后- s s t h r e s h = c w n d / 2 , c w n d = s s t h r e s h + 3 ∗ M S S ssthresh = cwnd/2, cwnd = ssthresh + 3*MSS ssthresh=cwnd/2,cwnd=ssthresh+3∗MSS
- 对于引起TCP进入快速恢复的缺失报文段,对收到的每个重复
ACK
,cwnd = cwnd + 1*MSS
,依旧处于快速恢复状态。
总结
- 初始阈值
ssthresh = 64KB
(或16
个MSS
),初始窗口cwnd = 1
- 当
cwnd < ssthresh
时,发送方处于慢启动阶段,cwnd
指数增长 - 当
cwnd ≥ ssthresh
时,发送方处于拥塞避免阶段,cwnd
线性增长 - 当出现
3
个重复ACK
事件时- s s t h r e s h = c w n d / 2 T C P R e n o : c w n d = s s t h r e s h + 3 ∗ M S S T C P T a h o e : c w n d = 1 ssthresh = cwnd/2\\TCP\ Reno:cwnd = ssthresh + 3*MSS \\TCP\ Tahoe:cwnd = 1 ssthresh=cwnd/2TCP Reno:cwnd=ssthresh+3∗MSSTCP Tahoe:cwnd=1
- 发方进入快速恢复阶段,此时每收到一个重复的
ACK
,cwnd
则增加1 MSS
;如果收到新的ACK
,cwnd = ssthresh
- 当出现超时事件时, s s t h r e s h = c w n d / 2 c w n d = 1 ssthresh = cwnd/2\\cwnd = 1 ssthresh=cwnd/2cwnd=1