第5章 运输层
运输层协议概述
进程间通信
- 运输层,属于面向通信部分的最高层,也是用户功能中的最底层
- 两个主机进行端对端的通信时,只有位于网络边缘部分的主机的协议栈才有运输层,网络核心部分中的路由器在转发分组时都只用到下三层的功能

- 逻辑通信 - 意思是好像是这样通信,但事实上并非真的这样通信
 
- 从IP层来说,通信的两端是两台主机 
- 从运输层角度看,通信的真正端点是主机中的进程 
- 端到端的通信是进程之间的通信 - 即主机A的某个进程和主机B的某个进程的通信,简称计算机之间的通信
 

- 网络层和运输层之间的区别 - 网络层是为主机之间提供逻辑通信
- 运输层为应用进程之间提供端到端的逻辑通信
 
- 基于端口的复用和分用  
- 运输层的屏蔽作用 - 运输层向高层用户屏蔽了下面网络核心的细节,使应用进程看见的就好像是两个运输层实体之间有一条端到端的逻辑通信信道
 
两种不同的运输协议
- 面向连接的TCP协议 - 尽管下面的网络是不可靠的,但这种逻辑通信信道就相当于一条全双工的可靠信道
 
- 无连接的UDP协议 - 逻辑通信信道是一条不可靠信道
 
运输层的两个重要协议
- 用户数据报协议 UDP(User Datagram Protocol)
- 传输控制协议 TCP(Transmission Control Protocol)
- 对等运输实体在通信时传送的数据单元叫做运输协议数据单元TPDU Transport Protocol Data Unit
TCP和UDP
| TCP | UDP | 
|---|---|
| TCDU是TCP报文段 segment | TCDU是UDP报文或用数据报 | 
| 面向连接的协议,提供面向连接的服务 | 无连接的协议,提供无连接服务 | 
| 支持点对点单播,不支持多播、广播 | 支持单薄、多播、广播 | 
| 提供可靠交付 | 不提供可靠交付 | 
| 复杂,应用于大多数应用:万维网、电子邮件、文件传送 | 简单,适用于多媒体应用 | 
- 使用UDP和TCP的应用和应用层协议  
- 需要解决的问题 - 主机上可能有多个进程同时通信,进程是动态创建和撤销的
 
- 运输层的UDP数据报和网络层的IP数据报的区别 - IP数据报需要经过许多路由器的存储转发
- UDP数据报是在运输层的端到端抽象的逻辑信道中传送的
 
- TCP报文段 - 也是在运输层的端到端逻辑信道中传送,是可靠的全双工信道
- 这样的信道不知道经过了哪些路由器,路由器也不知道运输层是否建立了TCP连接
 
运输层的端口
- 进程是用进程标识符来标志的 - 不应当由操作系统指派标识符,因为操作系统种类很多
- 所以需要有统一的方法来对TCP/IP体系的应用程序来进行标志
 

- 需要解决的问题 - 进程创建和撤销是动态的,发送方无法识别其他机器上的进程
- 更改接收报文的进程,不需要通知所有发送方
- 需要利用目的主机提供的功能来识别终点,不需要知道实现这个功能的进程
 
- 端口号 - 协议端口号 protocol port number - 简称端口 port
- 可以把端口想象成通信的终点,把报文交给目的主机的某一个目的端口,剩下工作由TCP完成
 
 
- 软件端口和硬件端口 - 不同概念
- 协议栈间抽象的协议端口是软件端口
- 路由器或交换机上的端口是硬件端口
- 硬件端口是不同硬件设备交互的接口
- 软件端口是应用层的各种协议进程和运输实体进行层间交互的一种地址
 
- TCP/IP运输层端口 - 16位端口号,允许有65536个端口号
- 端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程
- 两个计算机的进程通信,不仅要知道对方的端口号,还要知道对方的IP地址
 
- 两类端口 - 服务器端使用的端口号 - 熟知端口,一般是0-1023
- 登记端口号,1024-49151,为没有数值端口号的应用程序使用。使用这个范围的端口必须在IANA登记,防止重复
 
- 客户端使用的端口号 - 又称为短暂端口号,49152-65535,留给客户进程选择暂时使用
- 当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。
- 通信结束后,这个端口号可以给其他客户进程使用
 
 

- 熟知端口
 
用户数据报协议UDP
- UDP特点 - 无连接 - 发送数据之前不建立连接
 
- 尽最大努力的交付 - 不保证可靠交付
 
- 面向报文 - UDP一次交付一个完整的报文
 
- 没有拥塞控制 - 因此网络出现拥塞不会使源主机的发送速率降低,对某些实时应用很重要
 
- 支持一对一,一对多,多对一和多对多的交互通信 
- 首部开销小 - 只有8个字节,比TCP的20个字节的首部要短
 
 
- 面向报文的UDP - 发送方UDP对应用程序下发的报文,在添加首部后就向下交付给IP层 - UDP对应用层下发的报文,不合并拆分,而是保留报文的边界
- 无用报文多长,UDP一次发送一个
 
- 接收放UDP对IP层上交的UDP数据报,在去除首部之后就原封不动地交给上层应用 - 一次交付一个完整的报文
- 应用程序必须选择合适大小的报文 - 如果报文太长,UDP交给IP层后,IP层在传送时可能要分片,降低IP层效率
- 如果报文太短,UDP交给IP层后,IP数据报的首部的相对长度太大,也会降低IP层效率
 
 
 
UDP首部格式
- UDP数据报:首部字段+数据字段 - 首部字段有8个字节,4个字段组成,每个字段都是2个字节
 

- 在计算检验和时,临时把12字节的伪首部和UDP数据报连接在一起。

- 基于端口的分用 - 当运输层从IP层收到UDP数据报时,就根据首部中的目的端口,把数据报通过端口上交给进程
 
传输控制协议TCP
TCP特点
- 面向连接 
- 可靠交付的服务 
- 只能有两个端点 endpoint 
- 每一个TCP连接只能是点对点的 
- 全双工通信 
- 面向字节流 - TCP中的流指流入或流出的字节序列
- 虽然应用程序和TCP的交互是一次一个数据块,但TCP把应用程序下发的数据看成仅仅是一串无结构的字节流
 
- 面向流的TCP - 不保证接收方所受到的数据块和发送方发出的数据块具有对应大小的关系
- 但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样
 

- TCP不关心应用进程一次把多长的报文发送到TCP缓存
- TCO对连续的字节流进行分段,形成TCP报文段 - TCP注意点
 
- TCP连接是一条虚连接而不是物理连接 
- 不关心进程一次把多长的报文发送到TCP的缓存中
- 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应该包含多少个字节
- 可把太长的数据块划分成短的数据块
- 也可以等待积累有足够多的字节再构成报文段发送
TCP的连接
- TCP把连接作为最基本的抽象 - TCP连接就是由协议软件所提供的一种抽象
 
- 每一条TCP连接有两个端点 
- TCO连接的端点叫做套接字socket或插口 - 不是主机,不是IP地址,不是应用程序,也不是运输层的协议端口
 
- 端口号拼接到 (concatenated with) IP地址即构成了套接字  
- 套接字 socket = (IP地址 : 端口号)- 例如 socket = 192.169.1.20 : 2028
 
- TCP连接 ::= {socket1, socket2} = {(IP1: port1), (IP2:port2)}- 每一条TCP连接唯一地被通信两端的两个套接字所确定
 
- 同一个IP地址可以有很多个不同的TCP连接 
- 同一个端口号也可以出现在多个不同的TCP连接中 
Socket的不同含义
- 应用编程接口 API 称为 socket API, 简称为 socket。
- socket API 中使用的一个函数名也叫作 socket。
- 调用 socket 函数的端点称为 socket。
- 调用 socket 函数时其返回值称为 socket 描述符,可简称为 socket。
- 在操作系统内核中连网协议的 Berkeley 实现,称为 socket 实现。
可靠传输的工作原理
- IP网络所提供的是不可靠的传输
理想传输特点
- 传输信道不产生差错
- 不管发送方以多快速度发送,接收方总是来得及处理
- 实际网络不具备以上两个理想条件,必须使用可靠传输协议来实现在不可靠的传输信道上实现可靠传输
停止等待协议
- 每发送完一个分组就等待对方的确认,收到确认后再发送下一个分组 
- 全双工的通信双方既是发送方也是接收方 
- 无差错情况  
- 出现差错 - 接收方B会出现两种情况 - B接收M1时检测出了差错,丢弃M1
- M1在传输过程中丢失了,B什么都不知道
 
- 这两种情况下,B都不会发送任何信息 
- 但是A必须重发分组直到B正确接收,来实现可靠通信 
- 解决方法:超时重传 - A为每一个已发送的分组都设置了一个超时计时器
- A只要为在计时器到期前接收到确认,就撤销计时器,继续发送下一个分组
- 若A在计时器规定时间内没有收到确认,就认为分组错误或丢失,重新发送
 
- B回复的确认丢失或延迟了,A重发分组M1,B可能会收到重复的M1,B如何知道是否重复需求丢弃 
- 解决办法:编号 - A为每一个发送的分组进行编号,B收到的编号相同的分组就认为是重复分组,丢弃并确认
- B为发送的确认页进行编号,指示该确认是对哪一个分组的确认
- A根据确认及其编号,可以确定它是对哪一个分组的确认,避免重复发送,如果遇到重复的确认,直接丢弃
 
 

- 确认丢失 - B所发送的对M1的确认丢失了,A在设定的超时重传时间内就收不到确认,但A无法分辨出现的情况是 - A发送的分组出错
- A发送的分组丢失
- B发送的确认丢失
 
- 因此A在超时计时器到期后就要重传M1
- 假设B又收到了重复的分组M1,B采取的两个行动 - 丢弃这个重复分组M1,不向上层交付
- 向A发送确认(即使上次已经发送过确认了)
 
 
- 确认迟到 - 传输过程中没有出现差错,但是B对分组M1的确认迟到了
- A会收到重复的确认,直接丢弃
- B仍然会收到重复的M1,直接丢弃重复的M1,并重传确认分组
 

- 注意点 - 在发送完一个分组之后,必须暂时保留以发送的分组的副本,以备重发
- 分组和确认分组都需要进行编号
- 超时计时器的重传时间应当比数组在分组传输的平均往返时间更长一些
 
ARQ自动重传请求
- A总是可以收到对所有发出的分组的确认,如果A不断重传分组,但总是收不到确认,说明通信线路差 - 使用上述的确认和重传机制,就可以实现在不可靠的网络上实现可靠的通信
 
- 上述这种可靠传输协议称为自动重传请求ARQ - Automatic Repeat reQuest
- 重传的请求是自动进行的,接受发不需要请求发送方重传某个出错的分组
 
停止等待协议要点
- 停止等待 - 发送方每次发送一个分组,收到确认后再发送下一个
 
- 编号 - 对发送的每个分组和确认都进行编号
 
- 自动重传请求 - 发送方为每个分组设置一个超时计数器,若超时,则自动重传分组
 
- 简单;信道利用率低;
信道利用率
- 停止等待协议的优点是简单,缺点是信道利用率低
- 信道利用率 - #card=math&code=U%3DT_D%2F%28T_D%2BRTT%2BT_A%20%29) 
 

- 当往返时间RTT远大于分组发送时间TD时,信道利用率会非常低
- 如果出现重传,则对传送有用的数据信息来说,信道利用率就更低了
流水线传输
- 为了提高传输效率
- 流水线传输就是发送方可以连续发送多个分组,不必发送完一个分组停顿下来等待对方确认 - 信道上一直有数据不间断传送
- 信道利用率很高
 

连续ARQ协议
- 滑动窗口是TCP协议的精髓
- 发送方维持的发送窗口,位于发送窗口内的分组都可连续发送出去,不需要等待对方的确认
- 发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置

累计确认
- 接收方采取累计确认,不必对收到的分组逐个确认 - 只对按序到达的最后一个分组发送确认,表示到这个分组为止的所有分组都已经正确收到
 
- 优点 - 容易实现,即使确认丢失也不必重传
 
- 缺点 - 不能向发送方反映出接收方已经正确收到的所有分组的信息
 
后退N帧 Go-back-N
- 如果发送方发送了5个分组,中间的第3个分组丢失 - 接收方只能对前两个发出确认
- 发送方无法知道后面三个的下落,所以要重传后面三个分组
 
- 后退N帧,表示需要再退回来重传已发送过的N个分组
- 因此,当通信链路质量不好时,连续ARQ协议会带来负面效果
TCP实现可靠通信
- 每一个端必须有两个窗口 - 发送窗口 - 在没有收到确认的情况下, 可以连续把窗口内的数据全部发送出去
 
- 接收窗口 - 只允许接收落入窗口内的数据
 
 
- 可靠传输机制用字节的序号进行控制 - TCP所有的确认都是基于序号,不是基于报文段的
 
- TCP两端的四个窗口处于动态变化中
- RTT也不是固定不变的,需要用特定算法估算合理的重传时间

连续ARQ协议 vs 停止等待协议
| 连续ARQ协议 | 停止等待协议 | |
|---|---|---|
| 发送的分组数量 | 一次发送多个分组 | 一次发送一个分组 | 
| 传输控制 | 滑动窗口协议 | 停等-等待 | 
| 确认 | 单独确认 + 累积确认 | 单独确认 | 
| 超时定时器 | 每个发送的分组 | 每个发送的分组 | 
| 编号 | 每个发送的分组 | 每个发送的分组 | 
| 重传 | 回退N,多个分组 | 一个分组 | 
TCP报文段的首部格式
- 虽然TCP是面向字节流的,但是TCP传送的数据单元是报文段
- TCP报文段分为首部和数据,TCP的全体功能体现在首部各字段
- TCP报文段首部的前20个字节是固定的,后面有4n字节是根据需要增加的选项 - 因此TCP首部的最小长度是20字节
 

- 源端口和目的端口 - 各占2字节,端口是运输层和应用层的服务接口
- 运输层的复用和分用功能都要通过端口实现
 
- 序号 - 4字节,TCP连接中传送的数据流中的每一个字节都要编上一个序号
- 序号字段的值指本报文段所发送的数据的第一个字节的序号
- 例如要传送5000个字节的数据,报文段的最大数据长度为1000个字节,初始序号为1001
- 报文段1序号 = 1001,报文段2序号 = 2001,报文段3序号 = 3001,报文段4序号 = 4001,报文段5序号 = 5001
 
- 确认号字段 - 4字节,是期望收到对方的下一个报文段的数据的第一个字节的序号
 
- 数据偏移 - 4位,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远
- 数据偏移的单位是32位字(以4字节为计算单位)
 
- 保留字段 - 6位,保留今后使用,目前设为0
 
- 紧急URG - 当UGR = 1,表示紧急指针字段有效,告诉系统此报文段中有紧急数据,应尽快传送
 
- 确认ACK - 当ACK = 1时确认号字段有效
 
- 推送PSH - 接收TCP收到PSH = 1的报文段,就尽快交付给接受应用,不再等整个缓存都填满了后上交
 
- 复位RST - 当RST = 1时,表明TCP连接出现严重差错,必须释放连接,然后再重新建立运输连接
 
- 同步SYN - SYN = 1表示这是一个连接请求或连接接收报文
 
- 终止FIN - 用来释放一个连接,FIN = 1表明报文段的发送端的数据已经发送完毕,并要求释放运输连接
 
- 窗口字段 - 2字节,用来让对方设置发送窗口的依据,单位为字节
 
- 检验和 - 2字节,检验和字段检验的范围包括首部和数据这两部分
- 计算检验和时,要在TCP报文段的前面加入12字节的伪首部
 
- 紧急指针字段 - 指出在本报文段中紧急数据共有多少个字节
- 紧急数据放在本报位段数据的最前面
 
- 选项字段 - 长度可变,最初TCP只规定了一种选项,即最大报文段长度MSS - Maximum Segment Size,数据字典加上TCP首部才等于整个的TCP报文段
- MSS告诉对方TCP,我的缓存所能接收的报文段的数据字段的最大长度的是MSS个字节
 
- 窗口扩大选项 - 3字节,其中有一个字节表示位移值S,新的窗口值等于TCP首部中的窗口位数增大到16+S,相当于把窗口值向左移动S位后获得实际的窗口大小
 
- 时间戳选项 - 10字节,其中最主要的是时间戳值字段(4字节)和时间戳回送回答字段(4字节)
 
- 选择确认选项
 
- 填充字段 - 为了使整个首部长度是4字节的帧数倍
 
规定MSS的原因
- MSS和接收窗口没有关系
- 如果选择较小的MSS长度,网络的利用率会降低
- 如果TCP报文段非常长,那么IP层传输的时候会分成很多段,终点需要合并,传输出错需要重传,这些都会增大开销
- 因此MSS应尽可能大,只要IP层传输时候不需要再分片
TCP可靠传输的实现
以字节为单位的滑动窗口
- TCP使用流水线传输和滑动窗口协议来实现高效、可靠的传输 
- TCP的滑动窗口以字节为单位 
- 发送方A和接收方B分别维持一个发送窗口和一个接收窗口 - 发送窗口:在没有收到确认的情况下,可以连续把窗口内的数据全部发送出去
- 接收窗口:只允许接收落入窗口内的数据
 
- 发送方的应用进程把字节流写入TCP的发送缓存 
- 接收方的应用进程从TCP的接收缓存流种读取字节流 
- 发送缓存用来暂时存放 - 发送应用程序传送给发送方TCP准备发送的数据
- TCP已发送出但尚未收到确认的数据
 
- 接收缓存用来暂时存放 - 按序到达的、但尚未被接收应用程序读取的数据
- 不按序到达的数据
 
- 三个重点 - A的发送窗口不总是和B的接收窗口一样大 - 有一定的时间滞后
 
- TCP标准没有规定对不按序到达的数据应该如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程
- TCP要求接收方必须有累计确认的功能,可以减小传输开销
 
接收方的确认
- 接收方可以在合适的时候发送确认,也可以在自己要发送数据的时候顺带确认信息
- 注意点 - 接收方不应该过分推迟发送确认,因为会导致发送方不必要的重传,浪费网络资源
- 捎带确认实际上并不常发生,因为大多数应用很少同时在两个方向上发送数据
 
超时重传时间的选择
- 重传机制,复杂,重要 - 选择重传时间
 
- TCP每发送一个报文段,就设置一次计时器 - 只要计时器设置的重传时间到还没收到确认,就要重传报文段
 
- 设置TCP重传时间的难点 - 往返时延RTT的方差很大 - 因为TCP下层是互联网环境,IP数据报所选择的路由变化大,所以运输层的RTT方差很大
 
- 如果太短,就会有很多不必要的重传,网络负荷增大
- 如果太长,网络的空闲时间增大,传输效率降低
 
- TCP的自适应算法 - 记录一个报文段发出的时间,以及收到相应确认的时间
- 这两个时间之差就是报文段的往返时间
 
加权平均往返时间RTTs
- 又称平滑往返时间
- 第一次测量RTT样本时,RTTs为测量的样本值,之后每次更新 - 新的RTTs = (1-α) x 旧的RTTs + α x 新的RTT样本
- 0<= α <= 1,接近0表示RTT更新慢,接近1表示RTT更新快
- 推荐值为0.125
 
超时重传时间RTO
- Retransmission Time-Out
- 应该略大于RTTs
- 一般为 RTO = RTTs + 4 x RTT
- RTT是RTT的偏差的加权平均值 - 第一次测量时,RTT值为RTT样本的一样,之后每次更新
- 新的RTT = (1-β) x 旧的RTT + β x |RTTs - 新的RTT样本|
- β推荐值是0.25
 
计算平均往返时间RTT
- 如何判定确认报文ACK是对原来的报文段的确认,还是对重传报文段的确认?
- Karn算法 - 在计算平均往返时间RTT时,只要报文段重传了,就不采用其往返时间样本
 
- 这样得出的加权平均往返时间RTTs和超时重传时间RTO就较准确
- 新问题 - 当报文段的时延突然增大很多时
- 在原来的重传时间内,收不到确认报文段,就会重传报文
- 但是根据Karn算法,不会考虑重传的报文段的RTT样本
- 就不会更新超时重传时间
 
- 修正的Karn算法 - 每重传一次报文段,增大一些RTO
- 新的RTO = γ x 旧的RTO
- γ的典型值是2
 
- 当不在发生报文段的重传时,才根据报文段的往返时延更新平均往返时延RTT和超时重传时间RTO的数值
选择确认SACK
- Selective ACK 
- 解决的问题 - 若收到的报文段无差错,只是未按序号到达,能否只传送缺少的数据而不重传已经正确到达的接收方的数据
 
- 如果要使用选择确认,那么在建立TCP连接时就要在TCP首部的选项中加上“允许SACK”的选项,双方都必须事先商定好 
- 首部中的“确认号字段”用法不变,只是在TCP报文段的首部增加了SACK选项,以便报告收到的不连续的字节块的边界 - 由于首部选项的长度最多只有40字节,而指明一个边界就要用掉四字节,所以在选项中最多只能指明4个字节块的边界信息
 
TCP流量控制
- 流量控制 flow control - 让发送方的传送速率不要太快,既要让接收方来得及接收,也不要使网络发生堵塞
 
利用滑动窗口实现流量控制
- A向B发送数据,在建立连接时,B告诉A,我的接收窗口rwnd=400字节

可能发生死锁
- B向A发送了零窗口的报文段之后,B又向A发送rwnd=400的报文段
- 这个报文段丢失了,A一直等B,B一直等A
- 如果没有其他措施,这种互相等待的死锁局面会一直持续
- 因此,TCP为每一个连接设置了一个持续计时器 persistence timer
持续计时器
- 只要TCP连接的一方收到对方的零窗口通知,就启动该计时器
- 若计时器到期,就发送零窗口探测报文段(1字节),对方需要给出现在的窗口值
- 若窗口值仍然是零,那么发送方重新设置持续计时器
- 如果不是零,就解除了死锁
TCP的传输效率
- 三种机制控制TCP报文段的发送时机 - TCP维持一个变量,等于最大报文段长度MSS,只要缓存中存放的数据达到MSS字节,就组成一个TCP报文段发送
- 由发送方的应用进程指明要求发送报文段,即TCP支持的推送push操作
- 发送方的一个计时器期限到了,就把缓存的数据转入报文段发送出去
 
发送方糊涂窗口综合征
- 每次仅发送一个字节或很少字节数据时,有效数据传输效率很低

- 解决方法 - Nagle算法
 
- 若应用进程把发送的数据逐个字节送到TCP的发送缓存中,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来
- 当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组成一个报文段发送出去
- 同时对随后到达的数据进行缓存
- 只有收到前一个报文段的确认后才继续发送下一个报文段 - 当到达的数据达到发送窗口大小的一半或者报文段的最大长度时,就立即发送
 

接收方糊涂窗口综合征
- 当接收方的TCP缓冲区已满时,接收方会向发送方发送窗口大小为0的报文
- 若接收方的应用进程以交互方式每次只读取一个字节,接收方又发送窗口大小为一个字节的更新报文
- 发送方应邀发送一个字节的数据,于是接收窗口又满了

- 原因:接收方应用进程消耗数据太慢
- 解决方法 - 让接收方等待一段时间,当接收缓存能容纳一个最长的报文段或者接收缓存已经有一半空闲的空间时
- 接收方发送确认报文,告诉发送方它的接收窗口大小
 
TCP拥塞控制
拥塞控制的一般原理
- 某段时间内,如果对网络中某资源的需求超过了该资源能提供的可用部分,网络性能会变坏 - 这种现象叫做拥塞congestion
 
- 最坏结果:系统崩溃 
- 产生拥塞的可能原因 - 点缓存的容量小
- 链路容量不足
- 处理机的处理速率慢
- 拥塞本身进一步加剧拥塞∑ 对资源需求 > 可用资源 
 
- 增加资源能否解决拥塞? - 不能,而且不但不能,而且可能使网络性能更坏
- 增大缓存,但未提高输出链路的容量和处理机的速度,排队等待的时间将会大大增加,引起大量超时重传,解决不了网络拥塞
- 提高处理机处理的速率会将瓶颈转移到其他地方
 
- 拥塞控制和流量控制的区别  
- 拥塞控制的前提:网络能够承受现有的网络负荷 
- 拥塞控制是一个动态问题 
- 分组丢失是网络发生拥塞的征兆而不是原因 
- 拥塞控制本身会称为引起网络性能恶化、甚至引发死锁的原因 
开环和闭环控制
- 开环控制 - 在设计网络时,事先考虑周全,力求工作时不发生拥塞
- 思路 - 力争避免发生拥塞
 
 
- 闭环控制 - 基于反馈环路的概念,根据网络当前的运行状态采取相应控制措施
- 思路 - 在发生拥塞后,采取措施进行控制,消除拥塞
 
- 措施 - 监控网络系统,以便检测到拥塞在何时何处发生
- 将拥塞发生的信息传送到可采取行动的地方
- 调整网络系统的运行以解决出现的问题
 
 
监测网络拥塞
- 主要指标 - 由于缺少缓存空间而被丢弃的分组的百分比
- 平均队列长度
- 超时重传的分组数
- 平均分组时延
- 分组时研的标准差
 
- 这些指标的上升都标志着拥塞的增长
传递拥塞通知
- 发送通知拥塞发生的分组
- 在分组中保留表示拥塞状态的字段
- 周期性发出探测分组
采取行动的时机
- 过于频繁-> 系统产生不稳定的震荡
- 过于迟缓-> 行动失去实用价值
解决拥塞的两条思路
- 增加网络可用资源
- 减少用户对资源的需求
TCP的拥塞控制方法
- TCP采用基于窗口的方法控制拥塞,属于闭环控制方法
- 发送方维持一个拥塞窗口cwnd(Congestion Window)
- 发送方利用拥塞窗口根据网络的拥塞情况调整发送的数据量
- 发送窗口的值 = min(接收方窗口值,拥塞窗口值)
控制拥塞窗口的原则
- 网络没出现拥塞时,窗口可以增大一些,以便发送更多的分组,提高网络利用率
- 只要网络出现拥塞或可能出现时,就需要减小拥塞窗口,以减少注入到网络中的分组,换解拥塞
拥塞的判断
- 重传定时器超时 - 网络已经发生拥塞
 
- 收到三个重复的ACK - 预示可能会发生拥塞
 
TCP拥塞控制算法
- 慢开始 slow start - 目的:用来确定网络的负载能力或拥塞程度
- 思路:由小到大逐渐增大拥塞窗口的数值
- 变量 - 拥塞窗口,初始窗口值设为2至4个最大报文段,逐渐增大
- 慢开始门限,防止拥塞窗口增长过大引起网络拥塞
 
- cwnd控制方法- 每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个SMSS的数值
- 拥塞窗口每次的增加量 = min(N, SMSS)
- N时原来没被确认,但是现在刚被确认报文确认的字节数
- 当N< SMSS时,拥塞窗口每次的增加量要小于SMSS
 
- 用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理
 

- 发送方每收到一个对新报文段的确认(不算重传的),就使cwnd加1

- 使用慢开始算法后,每经过一个传输轮次(transmission round),拥塞窗口就会翻倍 - 一个传输轮次所经历的时间就是往返时间RTT
- 传输轮次强调的是,把拥塞窗口所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认
- 例如,拥塞窗口cwnd = 4,这时的往返时间RTT就是发送方连续发送4个报文段,并受到这4个报文段的确认,总共经历的时间
 
- 设置慢开始门限状态 - ssthresh- 当cwnd < ssthresh时,使用慢开始算法
- 当cwnd > ssthresh时,停止使用慢开始算法而改用拥塞避免算法
- 当cwnd = ssthresh时,既可使用慢开始算法,也可使用拥塞避免算法- 拥塞避免算法
 
 
- 当
- 思路:让拥塞窗口 - cwnd缓慢增大,避免出现拥塞
- 每经过一个传输轮次,拥塞窗口cwnd = cwnd+1
- 使拥塞窗口cwnd按线性规律缓慢增长
- 在拥塞避免阶段,具有加法增大additive increase的特点

- 无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(重传定时器超时) - ssthresh = max(cwnd/2, 2)
- cwnd = 1
- 执行慢开始算法
 
- 目的:迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压得分组处理完毕

- TCP连接初始化时,拥塞窗口设置为1,单位是报文段
- 慢开始门限得初值设为16个报文段,即ssthresh = 16
- 当cwnd = 24时,出现了网络拥塞,于是调整门限值ssthresh = cwnd/2 = 12,同时设置cwnd = 1,进入慢开始阶段
- 当cwnd = 16时,发送方一连收到3个对同一个报文段的确认,于是发送方改为执行快重传和快恢复算法
- 拥塞避免算法的注意点 - 并非能够完全避免拥塞
- 只是说在拥塞避免阶段把拥塞窗口控制为线性规律增长,使网络比较不容易出现拥塞- 快重传算法
 
 
- FR, Fast Retransmission 
- 发送方一连收到三个重复确认,就知道接收方确实没有收到报文段,就立即进行重传,这样就不会超时,发送方也不会误认为是出现拥塞 
- 使用快重传可以使整个网络的吞吐量提高约20% 
- 快重传并非取消重传计数器,而是可以更早地重传丢失的报文段 
- 快重传算法可以让发送方尽早知道发生了个别报文段的丢失 
- 要求接收方不要等待自己发送数据时才进行稍待确认,而是要立即发送确认,即收到了失序的报文段也要立即发送对已收到的报文段的重复确认 

- 快恢复算法 - FR, Fast Recovery 
- 当发送方收到连续三个重复的确认时,由于发送方认为网络很可能没有拥塞,所以不执行慢开始算法,而是执行快恢复算法 - 慢开始门限 ssthresh = 当前拥塞窗口 cwnd / 2
- 新拥塞窗口 cwnd = 慢开始门限 ssthresh
- 开始执行拥塞避免算法,使拥塞窗口缓慢线性增大
 
 
AIMD
- 在拥塞避免阶段,拥塞窗口是按照线性规律增大的,称为加法增大 Additive Increase
- 当出现超时或3个重复的确认时,就要把门限值设置为当前拥塞窗口值得一半,并大大减小拥塞窗口得数值,称为乘法减小 Multiplicative Decrease

发送窗口的上限
- 发送窗口的上限值应取为接收方窗口 - rwnd和拥塞窗口- cwnd这两个变量中较小的一个- 发送窗口的上限值 = min(rwnd, cwnd)
- 接收方的接受能力和网络的拥塞限制了发送方发送数据的速率
 
主动队列管理AQM
- TCP的拥塞控制和网络层的策略有联系
- 若路由器对某些分组的处理时间很长,那么这些分组中的TCP报文段经过很长时间才能到达终点,结果引起发送方超时,对这些报文段进行重传
- 重传会使TCP连接的发送端认为在网络中发生了拥塞,但实际上并没有发生
- 对TCP拥塞控制影响最大的使路由器的分组丢弃策略
FIFO处理规则
- 路由器通常按照先进先出的规则处理分组
- 当队列已满使,之后到达的所有分组会被丢弃,叫做尾部丢弃策略 tail-drop policy
- 路由器的尾部丢弃往往会导致一连串的分组的丢失,会使发送方出现超时重传,使TCP进入拥塞控制的慢开始状态
- 结果使TCP的发送方突然把数据的发送速率降低到很小的数值

全局同步
- 更为严重的是,网络中有很多TCP连接,这些连接中的报文段通常是在网络层的IP数据报中传送的
- 若发生路由器的尾部丢弃,就可能会同时影响很多TCP连接,结果许多TCP连接同时进入慢开始状态 - 这称为全局同步 global synchronization
 
- 全局同步会使全网通信量下降,在恢复正常后,通信量又突然增大很多
主动队列管理AQM
- Active Queue Management 
- 主动 - 不等到路由器的队列长度达到最大值是才开始丢弃,而是在队列达到某个警惕值时就开始主动丢弃
 
- 实现方法 - 随机早期检测 RED Random Early Detection
- 路由器的队列维护两个参数:队列长度最小门限TH和最大门限TH
- RED对每一个到达的分组都先计算平均队列长度L - 若平均队列长度小于最小门限TH,则将新到达的分组放入队列进行排队
- 若平均队列长度超过最大门限TH,则将新到达的分组丢弃
- 若平均队列长度在两者之间,则按照一定概率p将新分组丢弃
 
 

- 当L<TH时,丢弃概率=0 
- 当L>TH时,丢弃概率=1 
- 当TH<L<TH时,0<p<1 
- 在RED操作中,最难处理的就是丢弃概率p的选择,因为p并不是个常数,例如,按线性规律变化,从0变到p  
- 事实上RED的使用效果不太理想 
- AQM实际上是对路由器中的分组排队进行只能管理,不是简单丢弃队列尾部的分组
✨TCP运输连接管理
🎏TCP的连接建立
运输连接的三个阶段
- TCP是面向连接的协议
- 连接的三个阶段 - 连接建立
- 数据传送
- 连接释放
 
- TCP连接的管理就是使TCP连接的建立和释放都能正常进行
连接建立的3个问题
- 使每一方都能知道对方的存在 
- 要允许双方协商一些参数 - 例如最大窗口值,是否使用窗口扩大选项和时间戳选项以及服务质量 
- 能够对运输实体资源进行分配例如缓存大小和连接表中的项目 
客户—服务器方式
- 主动发起连接建立的进程叫客户client 
- 被动等待连接建立的应用进程叫做服务器server 
- TCP建立连接的过程叫做握手🤝 
- 握手需要在客户和服务器之间交换三个TCP报文段,称为三报文握手 
- 采用三次握手主要是为了防止已失效的连接请求报文段突然又传送到了,而产生错误 
- ✨连接建立的三次握手过程,假设主机A为客户,主机B为服务器 - B的TCP服务器进程先创建传输控制块TCB,准备接收客户进程的连接请求
 - A的TCP向B发出连接请求报文段,其首部中的同步位 - SYN = 1,并选择序号- seq = x,表明传送数据时的第一个数据字节的序号是- x
- B的TCP收到连接请求报文之后,如果同意就发回确认 - B在确认报文段中使SYN=1,ACK=1,其确认号ack = x + 1,自己选择的序号seq = y
 
- B在确认报文段中使
- A收到此报文段后向B给出确认,其 - ACK=1,确认号- ack = y+1- A在TCP通知上层应用进程,连接已经确立
- B的TCP收到主机A的确认后,也通知其上层应用进程,TCP连接已经建立
 
 
TCP的连接释放
- 数据传输结束后,通信双方都可以释放连接 
- 四报文握手 
- 连接释放的四次握手过程,假设主机A为客户,主机B为服务器 - A的应用进程先向TCP发出连接释放报文段,并停止发送数据,主动关闭TCO连接 - A把连接释放报文段首部的FIN = 1,其序号seq = u,等待B的确认
 
- A把连接释放报文段首部的
- B发出确认,确认号 - ack = u+1,而这格报文段自己的序号- seq = v- TCP服务器进程通知高层应用进程
- 从A到B这格方向的连接就释放了,TCP连接处于半关闭状态
- 此时若B发送数据,A仍要接收
 
- 若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接 - B释放连接的报文段首部FIN = 1,自己的序号seq = w,确认号ack = u+1
 
- B释放连接的报文段首部
- A收到连接释放的报文段后,必须发出确认 - 在确认报文段中,确认号ack = w+1,自己的序号seq = u+1
 
- 在确认报文段中,确认号
 

- A必须等待2MSL的时间 - 为了保证A发送的最后一个ACK报文段能到达B
- 防止已失效的连接请求报文段出现在本连接中
 
保活计时器
- 用来防止在TCP连接出现长时期的空闲
- 通常设置为2小时,若服务器超过2小时还没有收到客户的信息,就发送探测报文段
- 若发送了10个探测报文段(每个相隔75s)还没有相应,就假定客户出现故障,因而中断连接
TCP的有限状态机

- 箭头旁边的字表明引起变迁的原因或者表明发生状态变迁后又出现的动作
- 三种箭头 - 粗实线箭头表示对客户进程的正常变迁
- 粗虚线箭头表示对服务器进程的正常变迁
- 细线箭头表示异常变迁
 
 
 
 
 
 
                         
                                

