本章重点:
目录
一、传输控制协议 TCP概述
1.1 TCP最主要的特点
1.2 TCP的连接
1.3 TCP报文段的首部格式
二、TCP可靠传输的实现
2.1以字节为单位的滑动窗口
2.2超时重传时间的选择
三、 TCP的流量控制
3.1利用滑动窗口实现流量控制
3.2 TCP的传输效率
四、TCP的拥塞控制
4.1拥塞控制的一般原理
4.2 TCP的拥塞控制方法
4.2.1四大算法
4.2.2主动队列管理 AQM
五、TCP的运输连接管理
5.1 TCP的连接建立
5.2 TCP的连接释放
5.3 TCP 的有限状态机
每一条 TCP连接有两个端点,叫套接字或插口
套接字的表示方法是在点分十进制的 IP地址后面写上端口号,中间用冒号或逗号隔开
每一条 TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定
同一个 IP地址可以有多个不同的 TCP连接,而同一端口号也可以出现在多个不同的 TCP连接中
假定数据传输只在一个方向进行,A发送数据,B给出确认
根据 B 给出的窗口值,A 构造出自己的发送窗口
发送窗口表示:在没有收到 B 的确认的情况下,A 可以连续把窗口内的数据都发送出去
发送窗口里面的序号表示允许发送的序号
显然,窗口越大,发送方就可以在收到对方确认之前连续发送更多的数据,因而可能获得更高的传输效率
发送窗口的位置由窗口前沿和后沿的位置共同确定
- 后沿的变化情况分不动(没有收到新的确认)和前移(收到新的确认)
- 前沿通常是不断向前移动(没有收到新的确认),也可能不动(收到新的确认但对方通知的窗口变小)
图解发送方发送数据过程
发送缓存用来暂时存放
发送缓存和发送后沿是重合的
接收缓存用来暂时存放
注意
- A 的发送窗口并不总是和 B 的接收窗口一样大(因为有一定的时间滞后)
- TCP 标准通常把不按序到达的数据临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程
- TCP 要求接收方必须有累积确认的功能,这样可以减小传输开销
TCP记录一个报文段发出的时间,以及收到相应的确认的时间,时间差就是报文段的往返时间 RTT,TCP保留了加权平均往返时间 RTTs
第一次测量到 RTT 样本时,RTTs 值就取为所测量到的 RTT 样本值。以后每测量到一个新的 RTT 样本,就按下式重新计算一次 RTTs:
新的RTTs = (1 - a) * (旧的RTTs) + a * (新的RTT样本)
式中 0 <= a < 1。若 a 很接近于零,表示 RTT 值更新较慢。若选择 a 接近于 1,则表示 RTT 值更新较快
超时重传时间 RTO略大于加权平均往返时间 RTTs:RTO = RTTs + 4 * RTTd(RTTd 是 RTT 的偏差的加权平均值)
第一次测量时,RTTD 值取为测量到的 RTT 样本值的一半。在以后的测量中,则使用下式计算加权平均的 RTTD:
新的 RTTd = (1 - b) * (旧的RTTd) + b * ½RTTs - 新的 RTT 样本½
Karn算法
如何判定此确认报文段是对原来的报文段 1 的确认,还是对重传的报文段 2 的确认?
报文段每重传一次,就把 RTO 增大一些:
新的 RTO = g * (旧的 RTO) ,系数 g 的典型值是 2
当不再发生报文段的重传时,才根据报文段的往返时延更新平均往返时延 RTT 和超时重传时间 RTO 的数值
流量控制是让发送方的发送速率不要太快,要让接收方来得及接收
TCP的窗口单位是字节,不是报文段
从图看出,接收方的主机 B进行了三次流量控制,窗口最终减小到0,即不允许发送方再发送数据。这种使发送方暂停发送的状态将持续到主机 B重新发出一个新的窗口值为止
考虑一种情况。B 向 A 发送了零窗口的报文段后不久,B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd = 400 的报文段。但这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知,而 B 也一直等待 A 发送的数据。如果没有其他措施,这种互相等待的死锁局面将一直延续下去。为了解决这个问题,TCP 为每一个连接设有一个持续计时器
只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。若窗口仍然是零,则收到这个报文段的一方就重新设置持续计时器。若窗口不是零,则死锁的僵局就可以打破了。
用不同的机制来控制 TCP 报文段的发送时机
拥塞控制是防止过多的数据注入到网络中,这样可能使网络中的路由器或链路不致过载。前提是网络能承受现有的网络负荷
拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器以及与降低网络传输性能有关的所有因素。流量控制往往是指点对点通信量的控制,是端到端的问题
在许多情况下,甚至是拥塞控制机制本身成为引起网络性能恶化甚至发生死锁的原因。这点应引起重视
拥塞控制可分为开环控制和闭环控制
- 开环控制是在设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞
- 闭环控制是基于反馈环路的概念。属于闭环控制的有以下几种措施:
- 监测网络系统以便检测到拥塞在何时、何处发生
- 将拥塞发生的信息传送到可采取行动的地方
- 调整网络系统的运行以解决出现的问题
四大算法进行拥塞控制:慢开始,拥塞避免,快重传,快恢复
现假定:
下面讨论的拥塞控制也叫基于窗口的拥塞控制
发送方维持一个叫拥塞窗口 CWND的状态变量,它的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口等于拥塞窗口
控制拥塞窗口的原则:只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞
判断网络拥塞的依据是出现超时
慢开始
算法思路:由小到大逐渐增大拥塞窗口数值
初始拥塞窗口 cwnd 设置:不超过2至4个 SMSS的数值
在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个 SMSS 的数值,即 拥塞窗口cwnd每次的增加量 = min (N, SMSS)(N 是原先未被确认的、但现在被刚收到的确认报文段所确认的字节数)
使用慢开始算法后,每经过一个传输轮次,拥塞窗口 cwnd 就加倍。 而一个传输轮次所经历的时间其实就是往返时间 RTT
为防止拥塞窗口cwnd 增长过大引起网络拥塞,需设置一个慢开始门限
拥塞避免
每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是像慢开始阶段那样加倍增长
在拥塞避免阶段,拥塞窗口 cwnd 按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多
快重传
让发送方尽早知道发生了个别报文段的丢失
首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认
发送方只要一连收到三个重复确认,就知道接收方确实没有收到报文段,因而应当立即进行重传(即“快重传”)
快恢复
当发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,因此不执行慢开始算法,而执行快恢复算法:
- 慢开始门限 ssthresh = 当前拥塞窗口 cwnd / 2
- 新拥塞窗口 cwnd = 慢开始门限 ssthresh
- 开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大
慢开始和拥塞避免算法的实现举例
为了便于理解,图中的窗口单位不使用字节而使用报文段
发送端的发送窗口不能超过拥塞窗口 cwnd 和接收端窗口 rwnd 中的最小值。我们假定接收端窗口足够大,因此现在发送窗口的数值等于拥塞窗口的数值
当 TCP 连接进行初始化时,将拥塞窗口置为 1。慢开始门限的初始值设置为 16 个报文段,即 ssthresh = 16
TCP拥塞控制流程图
如果把拥塞控制和接收方对发送方的流量控制一起考虑,发送方的发送窗口的上限值应当取为接收方窗口 rwnd 和拥塞窗口 cwnd 这两个变量中较小的一个,即 发送窗口的上限值 = Min [rwnd, cwnd]
网络层的策略对 TCP 拥塞控制影响最大的是路由器的分组丢弃策略
路由器的队列通常都是按照“先进先出”FIFO的规则处理到来的分组。当队列已满时,以后再到达的所有分组(如果能够继续排队,这些分组都将排在队列的尾部)将都被丢弃。这就叫做尾部丢弃策略在网络中通常有很多的 TCP 连接,这些连接中的报文段通常是复用在网络层的 IP 数据报中传送的。在这种情况下,若发生了路由器中的尾部丢弃,就可能会同时影响到很多条 TCP 连接,结果使这许多 TCP 连接在同一时间突然都进入到慢开始状态。TCP称其为全局同步
运输连接有三个阶段:连接建立,数据传送,连接释放
TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户,被动等待连接建立的应用进程叫做服务器
TCP 建立连接的过程叫做握手。握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手
TCP 连接释放过程是四报文握手
数据传输结束后,通信的双方都可释放连接
TCP 连接必须经过时间 2MSL 后才真正释放掉
粗实线箭头表示对客户进程的正常变迁
粗虚线箭头表示对服务器进程的正常变迁
细线箭头表示异常变迁