0 本节主要内容
问题描述
解决思路
1 问题描述
1.1 知识回顾
利用如下拓扑对前面的知识进行回顾。
图1 拓扑图
问题:源主机
H
1
\textrm{H}_1
H1要和目的主机
H
2
\textrm{H}_2
H2进行通信,源主机
H
1
\textrm{H}_1
H1要构建数据包封装来自应用层的数据。根据MAC层和IP层首部字段信息,同学们可以去思考如何填充以下四个字段:(MAC目的地址,MAC源地址,IP源地址,IP目的地址)?
步骤:
- 源主机 H 1 \textrm{H}_1 H1知道自己的IP地址,以及要送达的目的主机 H 2 \textrm{H}_2 H2的IP地址,也知道自己的MAC地址,唯一不知道的信息是目的MAC地址,那么首先要解决的是目的MAC地址填哪个的?
- 根据前面的知识,我们知道 H 1 \textrm{H}_1 H1要填的目的MAC地址是路由器 R 1 \textrm{R}_1 R1接口0的MAC地址,那怎么才能知道接口0的MAC地址呢?
- 由于 H 1 \textrm{H}_1 H1主机在配置网络的时候配置了缺省网关,缺省网关就是接口0的IP地址,知道了接口0的IP地址,利用ARP协议,就可以知道接口0的MAC地址,这样就可以把数据包完整的构建出来了;
- 根据交换机的原理,数据包利用交换机转发机制转发到路由器 R 1 \textrm{R}_1 R1;
- 路由器 R 1 \textrm{R}_1 R1如何把数据交给目的主机 H 2 \textrm{H}_2 H2?利用数据包中目的IP地址查路由表,按照最长匹配原则,发现路由器 R 1 \textrm{R}_1 R1的路由表中的第二项匹配,也就是数据包要转发给接口1;
- 接下来就是接口1如何把数据包交给目的主机 H 2 \textrm{H}_2 H2的问题了?因为目的主机 H 2 \textrm{H}_2 H2和路由器 R 1 \textrm{R}_1 R1接口1处于同一个子网,又需要重新构建数据包,四个字段(MAC目的地址,MAC源地址,IP源地址,IP目的地址)的“MAC源地址,IP源地址,IP目的地址”都是已知的,只有MAC目的地址未知,同样利用ARP协议,就可以知道目的主机 H 2 \textrm{H}_2 H2的MAC地址,这样就可以把数据包完整的构建出来了;
- 再利用交换机转发机制,将数据包转发给目的主机 H 2 \textrm{H}_2 H2。
同学们也可以利用这个拓扑,复习一下如下知识:
- 交换机工作原理:在一个局域网中,如何利用交换机进行转发的?交换机中的转发表又是如何学习到的?
- 子网划分:给定一个网络号128.1.0.0/16,如何划分为拓扑所示的三个子网?
- IP分片:源主机 H 1 \textrm{H}_1 H1向目的主机 H 2 \textrm{H}_2 H2发送的数据包长度超过了以太网的运输能力,如何进行分片?分片的数据包又如何进行转发?到达目的主机后又如何进行重组?
- 路由选择协议:拓扑中路由器 R 1 \textrm{R}_1 R1和 R 2 \textrm{R}_2 R2的路由表是如何学习得到的?
- ARP协议:已知对方的IP地址,如何学习到对方的MAC地址?
1.2 问题描述
- 问题1:通过上面的描述,我们知道源主机 H 1 \textrm{H}_1 H1是如何把数据传输给目的主机 H 2 \textrm{H}_2 H2的,但是网络通信实际上是源主机 H 1 \textrm{H}_1 H1的一个进程和目的主机 H 2 \textrm{H}_2 H2的一个进程进行通信,又如何来表示这种进程间通信呢?
- 问题2:网络层提供的是尽最大努力交付的服务,换句话说,提供的是不可靠服务;面对有些应用,需要提供可靠服务,怎么办?
2 解决思路
2.1 进程间通信的问题:端口
- 复用:应用进程都可以通过运输层再传送到 IP 层(网络层)。
- 分用:运输层从 IP 层收到发送给应用进程的数据后,必须分别交付给指明的各应用进程。如何指明各应用进程?
实际网络存在如下的现象:
- 发送方很难获得接收方的进程id号,因为进程的创建和撤销都是动态的;
- 发送方实际上只需要接收方提供一个功能来识别终点,并不关心是哪个进程来实现这个功能,也就是说,实现这个功能的进程是接收方本地的事,发送方并不关心;
- 上面的意思可以换一种说法:接收方可以改变接收报文的进程,但不需要通知发送方。
解决方法:在运输层使用协议端口号 (protocol port number),简称为端口 (port)。把端口设为通信的抽象终点。
端口用一个 16 位端口号进行标志,允许有 65,535 个不同的端口号。
两大类、三种类型的端口:
常用的熟知端口:
2.2 可靠传输的问题:TCP协议
TCP协议包括四个重要的技术:
- 可靠传输协议:停止等待协议、连续ARQ协议(滑动窗口);
- 流量控制:滑动窗口协议;
- 拥塞控制;
- 连接建立与释放。
2.2.1 停止等待协议
根据图1的拓扑图,令A为源主机
H
1
\textrm{H}_1
H1,B为目的主机
H
2
\textrm{H}_2
H2:
- A 发送完分组 M 1 \textrm{M}_1 M1 后就暂停发送,等待 B 的确认 (ACK)。
- B 收到 M 1 \textrm{M}_1 M1 向 A 发送 ACK。
- A 在收到了对 M 1 \textrm{M}_1 M1 的确认后,就再发送下一个分组 M 2 \textrm{M}_2 M2。
问题:A 如何知道 B 是否正确收到了
M
1
\textrm{M}_1
M1 呢?
解决方法:超时重传
- A 为每一个已发送的分组设置一个超时计时器;
- A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M 2 \textrm{M}_2 M2 ;
- 若 A 在超时计时器规定时间内没有收到 B 的确认,就认为分组错误或丢失,就重发该分组。
信道利用率:
信道利用率 U = T D T D + RTT + T A \textrm{信道利用率} U = \frac{T_D}{T_D + \textrm{RTT} + T_A} 信道利用率U=TD+RTT+TATD
当往返时间 RTT \textrm{RTT} RTT 远大于分组发送时间 T D T_D TD 时,信道的利用率会非常低。
提高传输效率:流水线传输
由于信道上一直有数据不间断地传送,流水线传输可获得很高的信道利用率。
连续 ARQ 协议和滑动窗口协议采用流水线传输方式。
2.2.2 连续 ARQ 协议
发送窗口:
累积确认:
连续 ARQ 协议采用 Go-back-N(回退N)。
Go-back-N(回退N):表示需要再退回来重传已发送过的 N 个分组。当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。
2.2.3 TCP 报文段的首部格式
2.2.4 流量控制:发送窗口+接收窗口,滑动窗口协议,接收方控制发送方
流量控制 (flow control) :让发送方的发送速率不要太快,使接收方来得及接收。
利用滑动窗口机制可以很方便地在 TCP 连接上实现对发送方的流量控制。
- 发送窗口+接收窗口
- 发送方 A 和接收方 B 分别维持一个发送窗口和一个接收窗口。
- 发送窗口:在没有收到确认的情况下,发送方可以连续把窗口内的数据全部发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。
- 接收窗口:只允许接收落入窗口内的数据。
(1) 发送窗口
P
1
\textrm{P}_1
P1 = 后沿,
P
2
\textrm{P}_2
P2 = 当前,
P
3
\textrm{P}_3
P3 = 前沿。
P
3
−
P
1
\textrm{P}_3 - \textrm{P}_1
P3−P1 = A 的发送窗口(又称为通知窗口)
P
2
−
P
1
\textrm{P}_2 - \textrm{P}_1
P2−P1 = 已发送但尚未收到确认的字节数
P
3
−
P
2
\textrm{P}_3 - \textrm{P}_2
P3−P2 = 允许发送但尚未发送的字节数(又称为可用窗口)
(2) 接收窗口
强调三点:
- 第一,发送窗口是根据接收窗口设置的,但在同一时刻,发送窗口并不总是和接收窗口一样大(因为有一定的时间滞后)。
- 第二,TCP 标准没有规定对不按序到达的数据应如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。
- 第三,TCP 要求接收方必须有累积确认的功能,以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。但接收方不应过分推迟发送确认,否则会导致发送方不必要的重传,捎带确认实际上并不经常发生。
(3)利用可变窗口进行流量控制举例
A 向 B 发送数据,MSS = 100 字节。在连接建立时,B 告诉 A:“我的接收窗口 rwnd = 400(字节)”
问题:可能发生死锁:
解决思路:持续计时器 (persistence timer),只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。
- 若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),对方在确认这个探测报文段时给出当前窗口值。
- 若窗口仍然是零,收到这个报文段的一方就重新设置持续计时器。
- 若窗口不是零,则死锁的僵局就可以打破了。
2.2.5 滑动窗口协议带来的糊涂窗口综合症
糊涂窗口综合症:每次仅发送一个字节或很少几个字节的数据时,有效数据传输效率变得很低的现象。
-
发送方糊涂
问题描述:发送方 TCP 每次接收到一字节的数据后就发送。
解决方法:Nagle 算法。
-
接收方糊涂
问题描述:接收方应用进程消耗数据太慢,例如每次只读取一个字节。
解决方法:让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。
发送方和接收方相互配合使用上述方法,使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。
2.2.6 拥塞控制:拥塞窗口
- 问题描述:在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降。这种现象称为拥塞 (congestion)。
解决方法:TCP 采用基于滑动窗口的方法进行拥塞控制,属于闭环控制方法。
- TCP 发送方维持一个拥塞窗口 cwnd (Congestion Window);
- 拥塞窗口的大小取决于网络的拥塞程度,并且是动态变化的;
- 发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量;
- 发送窗口大小不仅取决于接收方窗口,还取决于网络的拥塞状况。
- 真正的发送窗口值 = Min (接收方通知的窗口值,拥塞窗口值)。
- 四种拥塞控制算法( RFC 5681):
- 慢开始 (slow-start)
- 拥塞避免 (congestion avoidance)
- 快重传 (fast retransmit)
- 快恢复 (fast recovery)
(1)慢开始 (slow-start)
方法描述:
- 当 cwnd < ssthresh 时,使用慢开始算法。
- 当 cwnd > ssthresh 时,停止使用慢开始算法,改用拥塞避免算法。
- 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞避免算法。
(2)拥塞避免 (congestion avoidance)
方法描述:每经过一个往返时间 RTT(不管在此期间收到了多少确认),发送方的拥塞窗口 cwnd = cwnd + 1。
慢开始和拥塞避免算法的实现举例:
(3)快重传 (fast retransmit)
方法描述:发送方只要连续收到三个重复的确认,就立即进行重传(即“快重传”),这样就不会出现超时。
(4)快恢复 (fast recovery)
方法描述:当发送端收到连续三个重复的确认时,不执行慢开始算法,而是执行快恢复算法 FR (Fast Recovery) 算法。
- 慢开始门限 ssthresh = 当前拥塞窗口 cwnd / 2 ;
- 乘法减小 MD (Multiplicative Decrease) 拥塞窗口。
新拥塞窗口 cwnd = 慢开始门限 ssthresh ; - 执行拥塞避免算法,使拥塞窗口缓慢地线性增大(加法增大 AI)。
快重传和快恢复算法的实现举例: