运输层
概述
运输层
向应用层
提供通信服务
(1)运输层
是面向通信
部分的最高层
(2)运输层
是用户功能
中的最底层
- 只有
主机
的协议栈才有运输层,而网络核心部分中的路由器
在分组转发时都使用到下三层的功能网络层
为主机
之间提供逻辑通信,而运输层
为应用进程
之间提供端到端的逻辑通信
- 复用和分用:
复用:
在发送方
不同的应用进程
都可以使用同一个运输层协议传输数据(需要加上适当的头部)分用:
是指接收方
的运输层
在剥去报文的首部后能够把这些数据正确交付目的应用进程
运输层端口
- 运输层使用
协议端口号(端口)
,当运输层收到IP层
交上来的运输层报文
时,能够根据目的端口号
把数据交付应用层的目的应用进程
- 两个计算机中的进程要相互通信,不仅必须知道对方的
IP地址
,而且要知道对方的端口号
- 服务器使用的端口号:
熟知端口号(系统端口号):
0 ~ 1023
登记端口号:
1024 ~ 49151
- 客户端使用的端口号:
客户端使用的端口号:
49152 ~ 65535
- 此类端口只能在客户进程运行时才动态选择,因此又叫做
短暂端口号
用户数据报协议UDP
UDP
是无连接的,使用尽最大努力交付, 即不保证可靠交付
UDP
是面向报文的:
(1)发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层
(2)UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界
(3)应用程序必须选择合适大小的报文,报文段太长,IP层在传送时需要进行分片,会降低IP层的效率UDP
没有拥塞控制
,因此网络拥塞不会使源主机的发送速率降低UDP
支持一对一
、一对多
、多对一
和多对多
的交互通信UDP
首部开销小,只有8
个字节
首部格式
用户数据报 = 数据字段 + 首部字段
首部字段 = 4字段 * 2字节
(1)源端口:
源端口号
(2)目的端口:
目的端口号
(3)长度:
用户数据报的长度,最小值是8(仅有首部)
(4)校验和:
检测用户数据报
在传输中是否有错,差错即丢弃
- 当
运输层
从IP层
收到用户数据报
时,就根据首部中的目的端口
,把用户数据报
通过相应的端口,上交给应用进程
- 若接收方
UDP
发现收到的报文中的目的端口号
不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议ICMP
发送端口不可达
差错报文给发送方- 虽然在
UDP
之间的通信要用到其端口号
,但由于UDP
的通信是无连接的
,因此不需要使用套接字
- UDP校验和:
- 在计算校验和时,要在
UDP用户数据报
之前增加12
个字节的伪首部
- 伪首部既不向下传送也不向上递交,而仅仅是为了计算校验和
IP数据报
的检验和只检验IP数据报
的首部
,但UDP的校验和
检验首部和数据
- 计算步骤:
(1)将全零放入检验和字段
(2)将伪首部及UDP数据报
看成由许多16位的字
串接起来的
(3)若UDP数据报
的数据部分
不是偶数个字节,则要填入一个全零字节(但此字节不发送)
(4)按二进制反码
计算出这些16位字的和
(5)将此和的二进制反码
写入校验和字段
后- 在接收方,将收到的
UDP用户数据报
连同伪首部
以及可能的填充全零字节
一起,按二进制反码
求这些16位字的和
(1)无差错:
结果应全为1
(2)出现差错:
结果不全为1,丢弃
传输控制协议TCP
TCP
是面向连接
的运输层协议- 每一个
TCP
连接只能是点对点的
TCP
提供可靠交付
的服务TCP
连接提供全双工通信
,TCP连接
的两端都设有发送缓存
和接收缓存
,用来临时存放双向通信的数据TCP
连接是面向字节流的:
(1)流:
流入进程或从进程流程的字节序列
(2)虽然用户程序
和TCP
的交互是一次一个数据块
(大小不等),但TCP
把应用程序
交下来的数据仅仅看成是一连串的无结构的字节流
TCP报文段
的长度
由接收方给出的窗口值rwd
和网络拥塞程度决定
而并不关心应用进程
一次把多长的报文发送到TCP的缓存中
套接字
TCP连接
的端点
叫做套接字(socket)或插口
套接字 socket = (IP地址 : 端口号)
- 每一条
TCP连接
唯一地被通信两端的两个端点
(两个套接字
)所确定- TCP连接 ::= {socket1, socket2} = {(IP1 :Port1), (IP2:Port2)}
- 同一个IP地址可以有多个不同的TCP连接,而同一个端口号也可以出现在多个不同的的TCP连接中
首部格式*
- 源端口和目的端口: 源端口号和目的端口号
- 序号(报文段序号):
本报文段
所发送的数据的第一个字节
的序号
- 在一个
TCP连接
中传送的字节流中的每一个字节都按顺序编号,确保通信的有序性,避免网络中的乱序问题- 初始的序列号由自己定,后续的序列号由对方的确认号决定
- 确认号: 期望收到对方
下一个报文段
的第一个数据字节
的序号
确认号 = N:
到序号 N − 1 N - 1 N−1为止的所有数据都已正确收到
- 数据偏移: 指出
TCP报文段
的数据起始处
距离TCP报文段
的起始处
有多远,单位是4个字节
- 保留: 置为0,保留为今后使用
- 控制位(6个):
- 紧急URG:
(1)当URG = 1
时,表明紧急指针字段有效,即告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
(2)发送方TCP
就把紧急数据
插入到本报文段数据的最前面
,而在紧急数据后面的数据仍是普通数据
(3)需要与首部中的紧急指针
字段配合使用- 确认ACK:
(1)仅当ACK = 1
时确认号字段才有效
(2)当ACK = 0
时,确认号无效
(3)TCP规定,在建立连接后
所有传送的报文段都必须把ACK
置为1
- 推送PSH:
(1)发送方TCP
把PSH
置为1,并立即创建一个报文段发送出去
(2)接收方TCP
收到PSH = 1
的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付- 复位RST:
(1)当RST = 1
时,表明TCP连接中出现严重差错
,必须释放连接,然后再重新建立运输连接
(2)当RST=1
还用来拒绝一个非法的报文段
或拒绝打开一个连接
- 同步SYN: 在连接建立时用来同步序号
(1)当SYN = 1
而ACK = 0
时,表明这是一个连接请求报文段
(2)若对方同意建立连接
,则应在响应的报文段中使用SYN = 1
和ACK = 1
- 终止FIN: 用来释放一个连接
(1)当FIN = 1
时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接
- 窗口: 发送本报文段的一方的
接收窗口
(而不是自己的发送窗口)
(1)窗口值
告诉对方,从本报文段首部中的确认号算起
,目前允许对方发送的数据量(以字节为单位
)
(2)窗口值
作为接收方让发送方设置其发送窗口
的依据
(3)窗口值
经常动态变化
- 检验和:
(1)检验范围:
首部+数据
(2)在计算检验和时,要在TCP报文段
的前面加上12字节
的伪首部
- 紧急指针:
(1)紧急指针仅在URG = 1
时才有意义
(2)紧急指针指出本报文段中的紧急数据
的字节数
TCP vs UDP *
UDP | TCP | |
---|---|---|
连接性 | 无连接 | 面向连接 |
可靠性 | 不可靠,无确认机制 | 可靠,有确认机制 |
流量控制 | 无 | 有 |
拥塞控制 | 无 | 有 |
连接对象个数 | 一对一、一对多、多对多 | 一对一 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 开销小,固定8字节 | 开销大,最小20字节、最大60字节 |
使用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,如文件传输等 |
可靠传输的原理
停止等待协议
停止等待:
每发送一个分组就停止发送,等待对方的确认,在收到确认
后再发送下一个分组
- 无差错时:
- A A A发送分组 M 1 M_1 M1,发完就暂停发送,等待 B B B的确认
- B B B收到了 M 1 M_1 M1就向A发送确认
- A A A收到了对 M 1 M_1 M1的确认之后,就再发送下一个分组 M 2 M_2 M2
- 同样,在收到 B B B对 M 2 M_2 M2的确认后,再发送 M 3 M_3 M3,如此循环往复
- 出现差错时:
出现差错地可能情况:
(1) B B B接收到 M 1 M_1 M1时检测出了错误,就丢弃 M 1 M_1 M1,其他什么也不做,即不通知 A A A收到有差错的分组
(2) M 1 M_1 M1在传输过程中丢失了,此时 B B B什么都不知道,因此 B B B也不会发送任何消息超时重传:
只要超过一定时间 A A A仍然没有收到 B B B的确认,就认为刚才发送的分组丢失了,因而重传
前面发送过的分组
- A A A在发送完一个分组后,必须
暂时保留
已发送的分组的副本(在发生超时重传时使用),只有收到相应的确认后才能清除暂时保留的分组副本分组
和确认分组
必须进行编号
超时计时器
设置的重传时间
应当比数据在分组传输的平均往返时间
更长一些
- 确认丢失:
- B B B所发送的对 M 1 M_1 M1的确认丢失了
- A A A在设定
超时时间
内没有收到确认,此时 A A A无法知道是发送的分组出错
、丢失
,还是 B B B发送的确认丢失了,因此 A A A在超时计时器到期后仍要重传 M 1 M_1 M1- 当 B B B收到了重传的分组 M 1 M_1 M1,应采取如下行动:
(1)丢弃这个重复分组 M 1 M_1 M1,不向上层交付
(2)再次向 A A A发送确认
- 确认迟到:
- 传输过程中没有出现差错,但 B B B对分组 M 1 M_1 M1的确认迟到了
- A A A会收到重复的确认,对
重复的确认
的处理:收下后丢丢弃
- B B B仍然会收到重复的分组 M 1 M_1 M1,并且同样要丢弃重复的 M 1 M_1 M1,并重传
确认分组
- 自动重传请求ARQ:
- 通过
确认和重传机制
,可以在不可靠的传输网络
上实现可靠的通信
自动重传请求ARQ:
重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组
(1)优点:
简单
(2)缺点:
信道利用率低
- 为了提高传输效率,发送方可以不使用低效率的
停止等待协议
,而是采用流水线传输
流水线传输:
发送方可连续发送多个分组,不必每发送完一个分组就停顿下来等待对方的确认- 通过
流水线传输
可以使信道上一直有数据不间断地在传送,可以获得较高的信道利用率- 当使用流水线传输时,需要使用
连续ARQ协议
和滑动窗口协议
连续ARQ协议
- 发送方维持了一个
发送窗口:
位于发送窗口内的分组都可以连续发出,而不需要等待对方的确认
- 接收方采用
累基确认
的方式
(1)接收方不必对收到的分组逐个发送确认
(2)在收到几个分组后,对按序到达
的最后一个分组
发送确认
(3)确认分组的含义:
到这个分组为止的所有分组都已正确收到- 优缺点:
(1)优点:
实现容易,即使确认丢失也不必重传
(2)缺点:
不能向发送方反映出接收方已经正确收到的所有分组的信息
Go-back-N
:
GO-back-N(回退N):
需要再退回来重传
已发送过的 N N N个分组举例:
(1)如果发送方发送了前5个分组,而中间的第三个分组丢失了
(2)此时接收方只能对前两个分组发送确认
(3)发送方无法知道后面3个分组的下落,而只好把后面的3个分组都再重传一次
可靠传输的实现
滑动窗口
- 在没有收到 B B B的确认的情况下, A A A可以连续把
发送窗口
内的数据发送出去- 凡是已经发送过的数据,在未收到确认之前都必须
暂时保留
,以便在超时重传
时使用发送窗口后沿的后面部分
为已发送且已收到了确认的字节,因此这些数据无需继续保留发送窗口前沿的前面部分
为不允许发送的字节
,因为接受方
没有为这部分数据保留临时存放的缓存空间
- 发送窗口后沿的变化:
不动:
未收到新的确认前移:
收到新的确认- 发送窗口后沿不可能向后移动,因为不能撤销已收到的确认
- 发送窗口前沿的变化:
- 通常情况下,发送窗口前沿会
不断向前移动
保持不动:
(1)没有收到新的确认,对方通知的窗口大小也不变
(2)收到了新的确认但对方通知的窗口缩小了,使得发送窗口前沿正好不动向后收缩:
(1)在对方通知的窗口缩小时,但TCP的标准强烈不赞成这样做
(2)因为很可能发送方在收到这个通知以前已经发送了窗口中的许多数据,现在又要收缩,不让发送这些数据,就会产生一些错误
- A的发送窗口:
- 要描述一个发送窗口的状态需要三个指针: P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3
- 指针小于 P 1 P_1 P1表示已发送并且已收到确认的部分,而大于 P 3 P_3 P3的是不允许发送的部分
- P 3 − P 1 = A 的 窗 口 大 小 P_3 - P_1 = A的窗口大小 P3−P1=A的窗口大小
- P 2 − P 1 = 已 发 送 但 尚 未 收 到 确 认 的 字 节 数 P_2 - P_1 = 已发送但尚未收到确认的字节数 P2−P1=已发送但尚未收到确认的字节数
- P 3 − P 2 = 允 许 发 送 但 当 前 尚 未 发 送 的 字 节 数 P_3 - P_2 = 允许发送但当前尚未发送的字节数 P3−P2=允许发送但当前尚未发送的字节数(
可用窗口
或有效窗口
)
- B的接收窗口:
- 到30号为止的数据为已经发送过确认,并且已经交付主机的数据,因此 B B B可以不再保留这些数据
- 接收窗口(31~50)是允许接收的, B B B只能对
按序收到的数据
中最后序号
给出确认,因此 B B B的确认报文段中的确认号
仍然是31(即期望收到的序号),而不能是32或33
- A A A继续发送完序号
42~53
的数据后,指针 P 2 P_2 P2向前移动与 P 3 P_3 P3重合,发送窗口内的序号都已用完,但仍未收到确认,因此 A A A必须停止发送数据- 有可能发送窗口内的所有数据都已正确到达 B B B, B B B也早已发出了确认,但所有 确 认 确认 确认都滞留在网络中
- 由于没有收到 B B B的确认, A A A在经过一段时间后(由
超时重传计时器
控制)就重传这部分数据,并重新设置 超 时 重 传 计 时 器 超时重传计时器 超时重传计时器,直到收到 B B B的确认为止
- 发送缓存与接收缓存:
缓存空间
和序号空间
都是有限且循环使用的
- 发送缓存:
存放的数据:
(1)发送应用程序
传送给发送方TCP准备发送的数据
(2)TCP已发送但尚未收到确认的数据
- 发送窗口通常只是发送缓存的一部分
- 已被确认的数据应当从发送缓存中删除, 因此发送缓存和发送窗口的后沿是
重合的
- 发送应用程序必须控制写入缓存的速率, 不能太快, 否则发送缓存就会没有存放该数据的空间
- 接收缓存:
存放的数据
(1)按序到达的、 但尚未被接收应用程序读取的数据
(2)未按序到达的数据- 若
接收应用程序
来不及读取收到的数据, 接收缓存最终就会被填满, 使接收窗口
减小到零- 如果
接收应用程序
能够及时从接收缓存
中读取收到的数据,接收窗口
就可以增大, 但最大不能超过接收缓存
的大小
- 虽然 A A A的
发送窗口
是根据 B B B的接收窗口
设置的, 但在同一时刻, A A A的发送窗口
并不总是和 B B B的接收窗口
一样大
(1)通过网络传送窗口值
需要经历一定的时间滞后
(2)发送方 A A A还可能根据网络当时的 拥 塞 情 况 拥塞情况 拥塞情况适当减小
自己的发送窗口数值TCP
通常对不按序到达的数据是先临时存放在接收窗口中, 等到字节流中所缺少的字节收到后, 再按序交付上层的应用进程- TCP要求接收方必须有
累积确认
的功能, 这样可以减小传输开销- 接收方可以在合适的时候发送确认, 也可以在自身发送数据时把确认信息顺便捎带上
- 接收方不应过分推迟发送确认, 否则会导致发送方不必要的重传, 这反而浪费了网络的资源
TCP的通信是全双工通信:
通信中的每一方都在发送和接收报文段,因此, 每一方都有自己的发送窗口
和接收窗口
超时重传时间
- 超时重传时间的选择:
超时重传时间
的选择是十分困难的:
(1)超时重传时间是基于报文段的往返时间
R T T RTT RTT确定的
(2) R T T RTT RTT的测量较为复杂,路由和网络资源的不同,它会随时间变化- 若
超时重传时间
设置得太短
, 会引起很多报文段的不必要的重传, 使网络负荷增大- 若
超时重传时间
设置得过长
, 会使网络的空闲时间增大, 降低了传输效率
- 超时重传时间的确定算法:
TCP
采用了一种自适应算法:
(1)记录1个报文段发出的时间及收到相应确认的时间
(2)这两个时间之差就是报文段的往返时间
R T T RTT RTT
(3)TCP
保存了RTT
的一个加权平均往返时间(平滑的往返时间)
R T T s RTT_s RTTs
(4) 新 R T T s = ( 1 − α ) × ( 旧 R T T s ) + α × ( 新 R T T 样 本 ) 0 ≤ α ≤ 1 新RTT_s = (1 - \alpha) \times (旧RTT_s) + \alpha \times (新RTT样本) \quad 0 \leq \alpha \leq 1 新RTTs=(1−α)×(旧RTTs)+α×(新RTT样本)0≤α≤1
(5)超时计时设置的重传时间
RTO应略大于
加权平均往返时间 R T T s RTT_s RTTs
选择确认(SACK)
选择确认:
SACK
是一个TCP
选项,可以允许接收方告诉发送方它正确接收到了次序杂乱
的数据- 与前后字节不连续的每一个
字节块
都有两个边界
:左边界
和右边界
- 如果要使用
选择确认
, 则在建立TCP
连接时, 要在TCP首部的选项
中加上允许SACK
的选项, 且双方必须事先商定好- 如果使用
选择确认
,那么原来首部中的确认号字段
的用法仍然不变,只是以后在TCP报文段
的首部中都增加了SACK选项
, 以便报告收到的不连续的字节块
的边界- 首部选项的长度最多只有40个字节,而指明一个边界就要用掉4个字节(序号为32位),因此在选项中最多只能指明4个字节块的边界信息
(1)4个字节块共有8个边界, 需要用32个字节来描述
(2)另外还需要2个字节: 一个字节用来指明是SACK 选项, 另一个字节是指明该选项的长度- 当收到
乱序数据
时,提供一个SACK
来描述乱序数据
,可以帮组对方有效地进行重传
- TCP如何实现可靠传输:
建立连接(标志位):
通信前确认通信实体是存在的序号机制(序号、确认号):
确保了数据的有序性和完整性数据校验(校验和):
用于校验TCP报文是否损坏超时重传(定时器):
接收方收到报文后就会确认,发送方一段时间后没有收到确认就会重传流量控制(窗口):
接收方通过滑动窗口控制发送方的发送速率,避免过量发送导致包丢失拥塞控制:
当网络发送拥塞时,通过拥塞窗口,减少数据发送,避免过量发送导致包丢失
流量控制
- 控制发送方的
发送速率
,使得接收方来得及接收接收方
通过控制发送方的发送窗口大小
来控制其发送速率- 发送方的
发送窗口
不能超过接收方给出的接收窗口
的数值
- 异常情况与持续计时器:
- 异常情况描述:
(1) B B B向 A A A发送了 r w d = 0 rwd=0 rwd=0的报文段后不久, B B B的接收缓存
又有了一些存储空间
(2)于是 B B B向 A A A发送了 r w d = 400 rwd = 400 rwd=400的报文段,但该报文段在传输过程丢失了
(3)此时 A A A将一直等待 B B B发送的非零窗口的通知,而 B B B也一直等待 A A A发送的数据- 解决方案:
(1)为每个TCP连接
设有一个持续计时器
,当TCP连接
的一方接收到对方的零窗口
通知,就启动持续计时器
(2)若持续计时器
设置的时间到期,就发送一个零窗口探测报文段
(仅携带1个字节的数据),而对方就在确认该探测报文段时给出了现在的窗口值
(3)若窗口仍然是0,那么收到这个报文段的一方就重新设置持续计时器;若窗口不是0,那么死锁的局面就可以打破了
发送时机
- 报文段的发送时机:
第一种机制:
TCP
维持1个变量,它等于最大报文段长度MSS
,只要缓存中存放的数据达到MSS字节时,就组装成1个TCP报文段
发送出去第二种机制:
由发送方应用进程指明要求发送报文段,即TCP
支持的推送
操作第三种机制:
发送方的一个计时器期限到了,就把当前已有的缓存数据装入报文段(但长度不能超过MSS)发送出去
- Nagle算法:
Nagle算法
是TCP的实现中广泛使用的发送控制机制- 基本原理:
(1)若发送应用进程
把要发送的数据逐个字节地送到TCP
的发送缓存
中, 则发送方就把第一个数据字节
先发送出去, 把后面到达的数据字节都缓存起来
(2)当发送方收到对第一个数据字符的确认后, 再把发送缓存中的所有数据组装成一个报文段发送出去, 同时继续对随后到达的数据进行缓存
(3)只有在收到对前一个报文段的确认后才继续发送下一个报文段
(4)此外,当到达的数据己达到发送窗口大小的一半或已达到报文段的最大长度时, 就立即发送一个报文段
传输效率
- 糊涂窗口综合征:
- 现象描述:
(1)TCP
接收方的缓存已满,而交互式应用进程一次只从接收缓存中读取一个字节(接收缓存空间仅腾出1个字节)
(2)然后向发送方发送确认,并把窗口设置为1(发送的数据报长度是40个字节)
(3)接着,发送方又发来1个字节的数据(发送方发送的IP数据报是41个字节)
(4)接收方发回确认,仍然将窗口设置为1个字节- 危害:
糊涂窗口综合征
长期进行下去,会使网络的效率很低- 解决方法:
(1)让接收方等待一段时间,或者接收方缓存已有足够空间容纳一个最长的报文段,或者等到接收方缓存已有一半空闲的空间时,接收方就发出确认报文,并向发送方通知当前窗口的大小
(2)发送方也不要发送太小的报文段,而是把数据累积成足够大的报文段,或达到接收方缓存空间的一半大小
拥塞控制*
- 拥塞: 若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏
- ∑ \sum ∑ 对资源的需求 > 可用资源
- 拥塞控制 vs 流量控制:*
- 控制目的:
(1)拥塞控制:
防止过多的数据注入到网络导致网络资源(路由器、交换机等)过载
(2)流量控制:
抑制发送端发送数据的速率,使接收端来得及接收- 参与者:
(1)拥塞控制:
全局性的过程
,涉及到通信链路全局
(2)流量控制:
点对点通信的控制
,是一个端到端的问题- 控制方式:
(1)拥塞控制:
拥塞窗口大小变化由试探性发送一定量数据探查网络状况后依据拥塞控制算法自适应调节
(2)流量控制:
通信双方各维护一个发送窗口一个接收窗口,接收窗口大小由自身决定,发送窗口大小由接收方响应的TCP报文段中窗口值确定
拥塞控制算法
TCP
进行拥塞控制的算法:慢开始、拥塞避免、快重传、快恢复
- 发送方维持一个
拥塞窗口(cwnd)
的状态变量
(1)拥塞窗口
的大小取决于网络的拥塞程度,且动态变化
(2)发送方让自己的发送窗口
等于拥塞窗口
- 控制原则:
(1)只要网络未出现拥塞,拥塞窗口就再增大一些,以便发送更多的分组,提高网络利用率
(2)只要网络出现拥塞或有可能出现拥塞,就把拥塞窗口减小,以减少注入到网络中的分组数,缓解网络出现的拥塞- 网络拥塞的判断标准:
出现超时
(1)只要网络发送拥塞时,路由器就要丢弃分组
(2)只要发送方没有按时收到应当到达的确认报文,即只要出现了超时重传时,就可以猜想网络可能出现了拥塞- 发 送 窗 口 的 上 限 值 = M i n [ r w n d , c w n d ] 发送窗口的上限值 = Min [rwnd, cwnd] 发送窗口的上限值=Min[rwnd,cwnd]
- 慢开始算法:
基本思路:
(1)当主机开始发送数据时,并不清楚网络的负荷情况
(2)所以先探测一下,即由小到大逐渐增大发送窗口
,即从小到大逐渐增加拥塞窗口
数值初始拥塞窗口(cwnd)数值
设置为2~4
个SMSS(发送方的最大报文段
)的数值- 慢开始规定,在每收到一个对新的
报文段的确认
后,可以把拥塞窗口增加最多一个SMSS
- 拥 塞 窗 口 c w d 每 次 增 加 量 = m i n ( N , S M S S ) 拥塞窗口cwd每次增加量 = min(N , SMSS) 拥塞窗口cwd每次增加量=min(N,SMSS),其中 N N N是原先未被确认,但现在被刚收到的确认报文所确认的字节数
- 慢开始并不是指
cwnd
的增长速率
慢,而是指在开始发送报文段时先设置cwnd = 1
,使得发送方在开始时只发送一个报文段,然后再逐渐增大cwnd
,相比设置大的cwnd
值一下将许多报文段注入网络要“慢得多”
- 为了防止拥塞窗口
cwnd
增长过大引起网络拥塞,还需设置一个慢开始门限(ssthresh)
:
(1)当cwnd < ssthresh
时,使用慢开始算法
(2)当cwnd > ssthresh
时,停止使用慢开始算法而改用拥塞避免算法
(3)当cwnd = ssthresh
时,既可以使用慢开始算法
,也可以使用拥塞避免算法
- 拥塞避免算法:
- 基本思路: 让拥塞窗口
缓慢地增大
,即每经过一个往返时间就把发送方的拥塞窗口
+1,而非慢开始阶段
的加倍增长- 拥塞避免的特点:
加法增大
,即拥塞窗口按线性规律
缓慢增长,调整到网络的最佳值
- 快重传算法:
- 采用
快重传算法
可以让发送方
尽早知道发生了个别报文段的丢失快重传算法
要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认
,即使收到了失序的报文段
也要立即发出对已收到的报文段的重复确认
快重传算法
规定:发送方只要一连收到3个重复确认
,就知道接收方确实没有收到某报文段,因此应立即进行重传(快重传)
, 这样就不会出现超时,发送方也就不会误认为出现了网络拥塞
- 快恢复算法:
- 当发送方知道现在只是丢失个别的报文,而非
网络拥塞
,于是不启动慢开算法
,而是快恢复算法
- 在快恢复算法中,发送方调整
门限值
ssthresh = cwnd / 2
,同时设置拥塞窗口cwnd = ssthresh
,并开始执行拥塞避免算法
主动队列管理(AQM)
- 在网络层,
路由器
的分组丢弃策略
对TCP拥塞控制
影响最大尾部丢弃策略:
路由器队列通常按照先入先出
规则来处理分组,当队列已满时,以后再到达的多余分组都将被丢弃尾部丢弃
会导致一连串分组的丢失,此时发送方会出现超时重传,使TCP进入拥塞控制
的慢开始状态,结果使TCP连接
的发送方突然把数据的发送速度降到很小的数值- 全局同步:
(1)在网络中通常有很多的TCP连接
,在这种情况下,若发生了路由器中的尾部丢弃
, 就可能会同时影响到很多条TCP连接
(2)结果使这许多TCP连接
在同一时间突然都进入到慢开始状态,全网的通信量突然下降很多
(3)在网络恢复后正常后,其通信量又突然增大很多
- 主动队列管理:
- 作用: 为了避免发生网络中的全局同步现象
主动:
(1)不要等到路由器的长度已经达到最大值时才不得不丢弃后面到达的分组
(2)应当在队列长度
达到某个值得警惕的数值时,即当网络拥塞有了某些拥塞征兆时,就主动丢弃到达的分组
- 随机检测(RED):
随机早期检测
是主动管理队列
的一种实现方法- 基本思路:
随机早期检测
使路由器维持两个参数:队列长度最小门限
、队列长度最大门限
(1)若平均队列长度小于最小门限
,则把新到达的分组放入队列进行排队
(2)若平均队列长度超过最大门限
,把新到达的分组丢弃
(3)若平均队列长度在最小门限
和最大门限
之间,则按照某一丢弃概率 p p p把新到达的分组丢弃
连接建立与释放*
- 运输连接的阶段:
连接建立
、数据传送
、连接释放
连接建立
- 建立过程:
- A A A打算建立
TCP连接
时,向 B B B发送连接请求报文
,此时首部中的同步位SYN = 1
,同时选择一个初始序号seq = x
(1)TCP
规定,SYN
报文段(SYN = 1
的报文段)不能携带数据
,但要消耗一个序号
, 此时TCP客户端
进入SYN-SENT(同步已发送)状态
(2)连接请求报文
中可能会含有一个或多个TCP选项
- B B B收到连接请求报文段后,若同意建立连接,则向 A A A发送确认
(1)在确认报文
中应把SYN
位和ACK
位都置为1,确认号是ack = x + 1
,同时也为自己选择一个初始序号seq = y
(2)确认报文段也不能携带数据
,但同样要消耗一个序号
,此时TCP服务器进程
进入SYN-RCVD(同步收到)状态
TCP客户端进程
收到B的确认后,还要向 B B B给出确认
(1)确认报文段的ACK = 1
,确认号ack = y + 1
,而自己的序号seq = x + 1
,TCP规定, ACK报文段可以携带数据
(2)但如果不携带数据则不消耗序号,这种情况下,下一个数据报文段的序号仍然是seq = x + 1
,此时,TCP连接
已经建立, A A A进入ESTABLISH(已建立连接)状态
- 当 B B B收到 A A A的确认后,也进入
ESTABLISH状态
- 为什么A最后还要发送一次确认?
- 为了防止
已失效的连接请求报文段
突然传到B,因而造成服务器资源浪费:
- A A A发出的第一个
连接请求报文
并没有丢失,而是在某些网络结点长时间滞留了,一直延误到连接释放以后的某个时间才到达 B B B- 该
链接请求报文
是一个早已失效的报文段,但 B B B收到此失效的连接请求报文段
后,就误以为 A A A又发一次新的连接请求,于是就向 A A A发送确认报文段
,同意建立连接- 假定不采用
报文握手
,那么只要 B B B发出确认,新的连接就建立了- 由于现在 A A A并没有发出
建立连接的请求
,因此不会理睬 B B B的确认,也不会向 B B B发送数据- 但 B B B却以为新的运输连接已经建立了,并一直等待 A A A发来数据,B的许多资源就白白浪费了
-
三次握手的目的:
(1)三次握手的主要作用是确认双方的接收和发送能力是否正常,指定自己的初始化序列号,交换TCP窗口大小信息,为后续的可靠性传输做准备
(2)第一次握手:客户端发送链接请求报文,服务端收到了,服务端可以得出结论:客户端的发送能力和服务端的接收能力是正常的
(3)第二次握手:服务端发包,客户端收到了,客户端得出结论:服务端的发送和接收能力都是正常的,客户端的发送和接收能力也是正常的,但服务端不能确认客户端的接收能力是否正常
(4)第三次握手:客户端发包,服务器收到了,服务器得出结论:服务端的发送和接收能力都是正常的,客户端的发送和接收能力也是正常的
(5)因此,需要三次握手才能确认双方的发送和接收能力是否正常 -
三次握手中为什么第1次不能携带数据,而第3次可以?
(1)若第一次握手可以携带数据,会使服务器更加容易受到攻击,因为恶意攻击者可能会在SYN报文中放入大量数据,同时可能会重复发送大量的SYN报文,这会让服务器花费很多时间和空间来接受报文
(2)第三次握手时,客户端已经处于ESTABLIST状态,对于客户端而言,TCP连接已经建立,并且已经知道服务器的接收和发送能力都是正常的,所以可以携带数据
连接释放
- 释放过程:
- 起初 A A A和 B B B都处于
ESTABLISHED状态
- A A A的应用进程先向其
TCP
发出连接释放报文
,并停止发送数据,主动关闭TCP连接
(1) A A A把连接释放报文段
首部的终止控制位FIN
置为1,其序号seq = u
,此时 A A A进入FIN-WAIT-1(终止等待1)
,等待 B B B的确认
(2)TCP
规定,FIN报文段
即使不携带数据,也要消耗掉一个序号- B B B接收到
连接释放报文
后即发出确认,确认号ack = u + 1
,该报文段的序号是v
,然后 B B B就进入CLOSE-WAIT(关闭等待)状态
(1)TCP服务器进程
这时应通知高层应用进程
,因而 A A A到 B B B这个方向的连接就释放了
(2)此时TCP连接
处于半关闭状态
,即 A A A已经没有数据要发送了,但 B B B若发送数据, A A A仍要接收- A A A收到来自 B B B的确认后,就进入
FIN-WAIT-2(终止等待2)状态
,等待 B B B发出的连接释放报文段
- 若 B B B已经没有要向 A A A发送的数据了,其应用进程就通知
TCP
释放连接
(1)这时 B B B发出的连接释放报文段
必须使FIN = 1
,现假定 B B B的序列号为w
(在半关闭状态 B B B可能又发送了一些数据), B B B还必须重复上次已发送过的确认号ack = u + 1
(2)这时 B B B就进入LAST-ACK(最后确认)状态
,等待 A A A的确认- A A A在收到 B B B的
连接释放报文段
后,必须对此发出确认
(1)在确认报文段中把ACK
置为1,确认号ack = w + 1
,而自己的序号是seq = u +1
(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)
(2)然后进入TIME-WAIT(时间等待)状态
,现在TCP连接还没有释放掉,必须经过时间等待计时器
设置的时间2MSL
后, A A A才进入到CLOSED状态
(3)MSL:
最长报文段寿命
- 为什么
A
A
A在
TIME-WAIT状态
必须等待2MSL
的时间呢?
- 为了保证 A A A发送的最后一个ACK报文段能够到达 B B B:
(1)若该ACK报文段
丢失,因而 B B B无法收到确认, B B B会超时重传这个FIN + ACK报文段
,而 A A A就能在2MSL
时间内收到该重传的FIN + ACK
报文段,接着 A A A重传一次确认,重新启动2MSL
计时器,最后, A A A和 B B B正常进入CLOSED状态
(2)如果 A A A在TIME-WAIT状态
不等待一段时间,而是发送完ACK报文段
后立即释放连接,那么就无法收到B重传的FIN + ACK报文段
,因而不会再发送一次确认报文段
,导致 B B B无法按照正常步骤进入CLOSED状态
- 防止已失效的连接请求报文段出现在本连接中:
(1) A A A在发送完最后一个ACK报文段
后,再经过2MSL
,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,因此可以保证下一个新的连接中不会出现旧的连接请求报文段
-
为什么TCP连接的建立需要三次握手,而TCP连接的释放需要四次挥手?
(1)在TCP连接时,当服务端收到客户端SYN连接请求报文后,可以直接发送SYN+ACK报文,其中ACK报文用于应答,SYN报文用于同步
(2)但是,在TCP连接断开时,当服务器收到FIN报文时,很可能服务器并互相立即关闭TCP连接,而是进入半关闭状态,所以只能先回复一个ACK报文,只有等服务器端所有的报文都发送完毕后,才能发送FIN报文,因此FIN和ACK不能一起发送,所以需要四次挥手 -
保活计时器:
- 作用: 防止
TCP连接
建立后,因客户端主机突发故障,导致服务器白白等待的现象发生- 解决方案:
(1)服务器
每收到一次客户端
的数据,就重新设置保活计时器(通常为2小时)
(2)若2小时没有收到客户
的数据,服务器
就发送一个探测报文段
,以后则每隔75秒发送一次
(3)若连续发送10个探测报文段
后仍无客户
的响应,服务器
就认为客户端出了故障,接着就关闭这个链接