第5章运输层
5.1 运输层协议概述
运输层的一个很重要的功能就是复用和分用。
5.1.1 进程之间的通信
运输层的主要功能
- 运输层为应用进程之间提供端到端的逻辑通信(但网络层是为主机之间提供逻辑通信)
- 报文差错检测
- 运输协议
IP数据报首部中的检验和字段,只检验收是否出现差错,而不检查数据部分。
5.1.2 运输层的两个主要协议
-
运输协议数据单元
Transport Protocol Data Unit
TPDU
- TCP 报文段(
segment
) UDP 报文或用户数据报
UDP
在传送数据之前不需要先建立连接,不需要给出任何确认TCP
不提供广播或多播服务
5.1.3 运输层的端口
16位端口号
1
. 服务器端使用的端口号
-
熟知端口号
well-known port number
,也称系统端口号,0~1023
登记端口号
1024~49151
- 动态选择,
49151~65535
2
. 客户端使用的端口号
5.2 用户数据报协议UDP
5.2.1 UDP概述
在IP层上增加的功能
- 复用,分用
- 差错检测
UDP特点
- 无连接
- 尽最大努力交付,即不保证可靠交付
- 面向报文,UDP不拆分或合并应用层报文
- 没有拥塞控制,很适合多媒体通信的要求。
- 支持一对多,多对多通信
- 首部小,只有8字节!
面向报文的 UDP
5.2.2 UDP的首部格式
每个字段的长度都是2个字节
- 源端口2B
- 目的端口2B
UDP
用户数据报的长度,其最小值是8
(仅有首部)2B- 检验和2B
伪首部的第3个字段是全零,第4个字段是IP首部中的协议字段的值,(对UDP来说是17),第5个字段是UDP用户数据报的长度。
我的看法,伪首部简介的保证了IP传送的时候最基本的信息不会出错,如果这些信息都出错了,就赶快抛弃,根本没有传下去的必要了。
5.3 传输控制协议TCP概述
5.3.1 TCP最主要的特点
- 面向连接
- 端点,点对点
- 可靠交付
- 全双工
- 面向字节流
-
流
stream
,流入到进程或从进程流出的字节序列
面向字节流
- 应用程序和TCP每次交互式一次一个数据块【大小不等】,但TCP把这些数据仅看成是一连串的无结构的字节流,不关注内容
TCP
不保证发送的数据块的接收的数据块具有大小对应关系,但是保证收发的字节流完全一样
5.3.2 TCP的连接
每一条TCP
连接唯一地被通信的两个端点(即两个套接字)所确定,UDP
是不是这样呢?
TCP连接的端点就是套接字。
同一个名词 socket有多种不同的意思
应用编程接口API
称为socket API
, 简称为socket
socket API
中使用的一个函数名也叫作socket
调用socket
函数的端点称为socket
调用socket
函数时其返回值称为socket
描述符,可简称为socket
在操作系统内核中连网协议的 Berkeley 实现,称为socket
实现
5.4 可靠传输的工作原理
理想的传输条件有以下两个特点:
- 传输信道不产生差错
- 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
在这样的理想传输条件下,不需要采取任何措施就能够实现可靠传输
运输层传送的协议数据单元叫做报文段,网络层传送的协议数据单元叫做IP数据报,二者都可以简称为分组。
5.4.1 停止等待协议
1.
无差错情况
2.
出现差错情况
-
超时重传
- 超时计时器
注意
- 必须暂时保留已发送的分组的副本
- 分组和确认分组都要编号
- 超时重传时间应当比数据在分组传输的平均往返时间更长一些
3.
确认丢失和确认迟到**
确认丢失处理
1. 丢弃这个重复的分组
2. 向发送方再次发送确认,不能认为已经发送过确认就不再发送,因为发送方之所以重传分组就表示没有收到确认
-
确认迟到处理
- 对重复的确认处理很简单,收下后就丢弃 自动重传请求
Automatic Repeat reQuestARQ
表明重传的请求是自动进行的。接收方不需要请求发送方重传某个出错的分组 。
ARQ
4.
信道利用率
-
RTT
- 往返时间 TD
- 发送分组所需要的时间 TA
- 发送确认分组所需要的时间 总时间
- TD+TA+RTT
信道利用率
一般的
-
流水线传输
- 连续
ARQ
协议和滑动窗口协议
5.4.2 连续ARQ
协议
- 位于发送窗口内的分组都可以连续发送出去,而不需要等待对方的确认
发送窗口
连续
ARQ
协议规定发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。
-
累计确认
- 接收方不必对收到的分组逐个发送确认,而是可以在收到几个分组后,对按序到达的最后一个分组发送确认
优点是:容易实现,即使确认丢失也不必重传。
缺点是:不能向发送方反映出接收方已经正确收到的所有分组的信息。
-
GBN
Go-back-N
,表示需要再退回来重传已发送过的 N 个分组。可见当通信线路质量不好时,连续ARQ
协议会带来负面的影响。
TCP 可靠通信的具体实现
TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。
TCP 的可靠传输机制用字节的序号进行控制。TCP所有的确认都是基于序号而不是基于报文段。
TCP 两端的四个窗口经常处于动态变化之中。
TCP连接的往返时间 RTT 也不是固定不变的。需要使用特定的算法估算较为合理的重传时间。
5.5 TCP报文段的首部格式
编号 | 内容 | 大小 | 作用 |
---|---|---|---|
1 | 源端口和目的端口 | 16位,2字节 | 实现运输层的复用和分用 |
2 | 序号*** | 32位,4字节 | 每一个字节都按顺序编号* |
3 | 确认号*** | 32位,4字节 | 期望收到对方下一个报文段的第一个数据字节的序号** |
5 | 数据偏移 | 4位,0.5个字节 | 指出TCP报文段的首部长度,以4字节为单位**** |
6 | 保留 | 6位 | |
7 | URG | 1位 | |
8 | ACK | 1位 | ACKnowlegment ,连接建立之后所有传送的报文段都必须把ACK置1 |
9 | PSH | 1位 | PuSH |
10 | RST | 1位 | ReSet |
11 | SYN | 1位 | SYNchronization ,链接请求报文段 |
12 | FIN | 1位 | |
13 | 窗口 | 16位,2字节 | 窗口值作为接收方让发送方设置其发送窗口的依据,最大窗口大小为64KB |
14 | 检验和 | 16位,2字节 | 计算是要加上12字节的伪首部,检验范围包括首部和数据两部分 |
15 | 紧急指针 | 16位,2字节 | |
16 | 选项 | 最长可达40字节 |
*首部中的序号字段值则是本报文段所发送的数据的第一个字节序号,一报文段的许哈字段值是301,携带的数据共有100字节,第一个字节的序号是301,最后一个字节的序号是400
**若确认号为=N,则表明到序号N-1为止的所有数据都已正确收到,
***由于序号字段有32位,可对4GB的数据进行编号
****4位最大就是1111=15,故TCP报文段首部的最大长度为60字节
-
最大报文段长度
Maximum Segment Size
,MSS是每一个TCP报文段中数据字段的最大长度。数据字段加上TCP首部才等于整个TCP报文段。所以MSS并不是整个TCP报文段的最大长度,而是”TCP报文段长度减去TCP首部长度”。MSS默认值是536字节,加上20字节的固定首部长度等于556字节。
MSS
其他选项
1. 窗口扩大选项 ——占 3 字节,其中有一个字节表示移位值 S。新的窗口值等于TCP 首部中的窗口位数增大到(16 + S),相当于把窗口值向左移动 S 位后获得实际的窗口大小。获得更高的吞吐量
2. 时间戳选项——占10 字节,其中最主要的字段时间戳值字段(4 字节)和时间戳回送回答字段(4 字节)。计算RTT,防止序号绕回
3. 选择确认选项SACK
5.6 TCP可靠传输的实现
A发送数据,B给出确认
5.6.1 以字节为单位的滑动窗口
-
发送窗口
- 在没有收到B的确认情况下,A可以连续把窗口内的数据都发送出去【不动】【前移】
发送窗口也可能向后收缩,TCP标准强烈不赞成这样做。
发送窗口通知窗口 = 已发送单位收到确认的字节数 + 允许发送单尚未发送的字节数可用窗口
缓存空间和序号空间都是有限的,并且都是循环使用。
发送缓存与接收缓存的作用
发送缓存用来暂时存放:
- 发送应用程序传送给发送方 TCP 准备发送的数据;
- TCP 已发送出但尚未收到确认的数据。
接收缓存用来暂时存放:
- 按序到达的、但尚未被接收应用程序读取的数据;
- 不按序到达的数据。
5.6.2 超时重传时间的选择
往返时延的方差很大
-
加权平均往返时间
- RTTS又称为平滑的往返时间,S–>
Smoothed
-
超时重传时间
RTO
,Retransmission Time-Out
往返时间的测量相当复杂
TCP 报文段 1 没有收到确认。重传(即报文段 2)后,收到了确认报文段 ACK。如何判定此确认报文段是对原来的报文段 1 的确认,还是对重传的报文段 2 的确认?
Karn 算法
在计算平均往返时间 RTT 时,只要报文段重传了,就不采用其往返时间样本。
这样得出的加权平均平均往返时间 RTTS 和超时重传时间 RTO 就较准确。
–
5.6.3 选择确认SACK
若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送少传的数据而不重传已经正确到达接收方的数据?
-
选择重传
Selective ACK
如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。
5.7 TCP的流量控制
5.7.1 利用滑动窗口实现流量控制
-
流量控制
- 就是让发送方的发送速率不要太快,要让接收方来得及接收。 流量控制的原理
- 原理这就是运用TCP报文段中的窗口大小字段来控制,发送方的发送窗口不可以大于接收方发回的窗口大小。 接收窗口rwnd
receiver window
发送方的发送窗口不能超过接收方给出的接收窗口的大小
TCP的窗口单位是字节,而不是报文段
-
大写的ACK
- 表示首部中的确认位 小写的ack
- 表示确认字段的值 持续计时器
persistence timer
,考虑情况B向A发送了rwnd=0
后,又发送了rwnd=400
【这个报文段丢失了】。只要TCP连接的一方收到零窗口通知,就启动持续计时器,到期就发送一个零窗口的探测报文段,对方给出现在的窗口值。若窗口仍然是零,则收到这个报文段的一方就重新设置持续计时器。若窗口不是零,则死锁的僵局就可以打破了
5.7.2 必须考虑传输效率
控制TCP报文段的发送时机
- 缓存中数据达到
MSS
字节时就发送 - 应用进程负责,即
TCP
的push
操作 - 发送方计时器到期发送
-
Nagele算法
- 广泛使用,只有收到前一个报文段的确认后才发送下一个报文段,当到达的数据已达到发送窗口大小的一般或MSS时,立即发送一个报文段。 糊涂窗口综合症
silly window syndrome
,接收缓存已满,接收方进程每次只读取很少的数据。每次空出来一点点地方就通知发送方,浪费网络。
5.8 TCP的拥塞控制
5.8.1 拥塞控制的一般原理
资源
- 带宽
- 交换结点的缓存和处理机
-
拥塞
congestion
,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏
拥塞常常趋于恶化。拥塞引起的重传并不会缓解网络的拥塞,反而会加剧网络的拥塞。
-
拥塞控制
- 防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。 前提
- 网络能够承受现有的负荷
拥塞控制是个全局性的过程。流量控制往往指点对点通信量的控制,是个端到端的问题。流量控制所要做的就是抑制发送端发送数据,以便接收端来得及接收。
进行拥塞控制需要付出代价!
对比
拥塞控制 | 流量控制 |
---|---|
带宽1Mb/s ,1000台大型机连在网络上,发送速率100kb/s | 带宽1000Gb/s ,巨型机向PC发送数据速率1Gb/s |
拥塞控制和流量控制之所以常常被弄混,是因为某些拥塞算法是向发送端发送控制报文,并告诉发送端,网络已经出现麻烦,必须放慢发送速率。这点又和流量控制室很相似的。
拥塞控制所起的作用
-
提供的负载
offered load
,代表单位时间内输入给忘了的分株数目
吞吐量
throughput
,代表单位时间内从网络输出的分组数目
拥塞控制的一般原理
拥塞控制是很难设计的,因为它是一个动态的(而不是静态的)问题。
当前网络正朝着高速化的方向发展,这很容易出现缓存不够大而造成分组的丢失。但分组的丢失是网络发生拥塞的征兆而不是原因。
在许多情况下,甚至正是拥塞控制本身成为引起网络性能恶化甚至发生死锁的原因。这点应特别引起重视。
5.8.2 几种拥塞控制方法
- 慢开始,
slow-start
- 拥塞避免,
congestion advoidance
- 快重传,
fast retransmit
- 快恢复,
fast recover
1.
慢开始和拥塞避免
-
拥塞窗口 cwnd
- 发送方维持一个叫做拥塞窗口
cwnd (congestion window)
的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。如再考虑到接收方的接收能力,则发送窗口还可能小于拥塞窗口。
发送方控制拥塞窗口的原则
- 只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
-
慢开始算法的原理
- 发送之前先探测一下,由大到小逐渐增大发送窗口即拥塞窗口数值
在主机刚刚开始发送报文段时可先设置拥塞窗口
cwnd = 1
,即设置为一个最大报文段MSS
的数值
在每收到一个对新的报文段的确认后,将拥塞窗口加 1
用这样的方法逐步增大发送端的拥塞窗口 cwnd,可以使分组注入到网络的速率更加合理。
-
传输轮次(transmission round)
- 使用慢开始算法后,每经过一个传输轮次,拥塞窗口
cwnd
就加倍。一个传输轮次所经历的时间其实就是往返时间 RTT。往返时间 RTT 就是发送方连续发送几个报文段,并收到这几个报文段的确认,总共经历的时间。
慢开始的慢并不是指
cwnd
的增长速率慢,而是指在TCP
开始发送报文段时先设置cwnd=1
,使得发送方在开始是只发送一个报文段,然后再逐渐增大cwnd
。
就像一群小鸟慢慢起飞
设置慢开始门限状态变量ssthresh
慢开始门限ssthresh
的用法如下:
当 cwnd < ssthresh 时,使用慢开始算法。
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
-
拥塞避免算法的思路
- 是让拥塞窗口
cwnd
缓慢地增大,即每经过一个往返时间RTT
就把发送方的拥塞窗口cwnd
加 1,而不是加倍,使拥塞窗口 cwnd 按线性规律缓慢增长。
当网络出现拥塞时
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认),就要把慢开始门限
ssthresh
设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。
然后把拥塞窗口cwnd
重新设置为 1,执行慢开始算法。
这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
- 是指不论在慢开始阶段还是拥塞避免阶段,只要出现一次超时(即出现一次网络拥塞),就把慢开始门限值 ssthresh 设置为当前的拥塞窗口值乘以 0.5。
当网络频繁出现拥塞时,ssthresh 值就下降得很快,以大大减少注入到网络中的分组数。
加法增大(additive increase)
- 是指执行拥塞避免算法后,在收到对所有报文段的确认后(即经过一个往返时间),就把拥塞窗口 cwnd增加一个 MSS 大小,使拥塞窗口缓慢增大,以防止网络过早出现拥塞。
乘法减小(multiplicative decrease)
- “拥塞避免”并非指完全能够避免了拥塞。利用以上的措施要完全避免网络拥塞还是不可能的。
- “拥塞避免”是说在拥塞避免阶段把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。
2.
快重传和快恢复
-
快重传
- 快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方。发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段。
不难看出,快重传并非取消重传计时器,而是在某些情况下可更早地重传丢失的报文段。
快恢复算法
1. 当发送端收到连续三个重复的确认时,就执行“乘法减小”算法,把慢开始门限 ssthresh 减半。但接下去不执行慢开始算法。
2. 由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,即拥塞窗口cwnd
现在不设置为 1,而是设置为慢开始门限ssthresh
减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。
从连续收到三个重复的确认转入拥塞避免
发送窗口的上限值
发送方的发送窗口的上限值应当取为接收方窗口 rwnd 和拥塞窗口 cwnd 这两个变量中较小的一个,即应按以下公式确定:
发送窗口的上限值 = Min [rwnd, cwnd]
当 rwnd < cwnd 时,是接收方的接收能力限制发送窗口的最大值。
当 cwnd < rwnd 时,则是网络的拥塞限制发送窗口的最大值。
5.8.3 随机早期检测RED
5.9 TCP的运输连接管理
1.
运输连接的三个阶段
运输连接就有三个阶段,即:连接建立、数据传送和连接释放。运输连接的管理就是使运输连接的建立和释放都能正常地进行。
连接建立过程中要解决以下三个问题:
要使每一方能够确知对方的存在。
要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。
能够对运输实体资源(如缓存大小,连接表中的项目等)进行分配。
客户-服务器方式
TCP 连接的建立都是采用客户服务器方式