第五章 运输层

第五章 运输层

5.1 运输层协议概述

5.1.1 进程之间的通信

从通信和信息处理的角度看,运输层向上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能的最底层。

从运输层的角度看,通信的真正端点并不是主机而是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。

运输层的复用分用

复用:发送方不同的应用进程都可以使用同一个运输层协议传送数据(当然需要加上合适的首部),

分用:接收方的运输层在剥去报文的首部后能够把这些数据正确交付目的应用进程。

IP层的复用和分用。

复用:发送方不同协议的数据都可有封装成IP数据报发送出去

分用:而在接收方的IP层根据IP首部中的协议字段进行分用,把剥去的首部后的数据交付应当接收这些数据的协议

网络层为主机之间提供逻辑通信;运输层为应用进程之间提供端到端的逻辑通信

运输层要对收到的报文进行差错检测;而在网络层,IP数据报首部中的检验和字段,只检验首部是否出现差错而不检查数据部分。

根据应用进程的不同需求,分为面向连接的TCP无连接的UDP

运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道

当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的(只提供尽最大努力服务),但这种逻辑通信信道就相当于一条全双工的可靠信道。但当运输层采用无连接的UDP协议时,这种逻辑通信信道仍然是一条不可靠信道

5.1.2 运输层的两个主要协议

主要协议:

  1. 用户数据报协议UDP不需要建立连接;不提供可靠交付,但某些情况下却是一种最有效的工作方式)----单位:UDP用户数据报

  2. 传输控制协议TCP提供面向连接的服务;提供可靠的,面向连接的运输服务)----单位:TCP报文段

传送数据单位:运输协议数据单元TPDU

5.1.3 运输层的端口

硬件端口:不同硬件设备进行交互的接口

软件端口:应用层的各种协议进程与运输实体进行层间交互的一种地址

端口号只具有本地意义

  1. 服务器端使用的端口号

    1. 熟知端口号系统端口号,数值为0~1023。

      应用程序FTPTELNETSMTPDNSTFTPHTTPSNMPSNMP ( t r a p ) _{(trap)} (trap)HTTPS
      熟知端口号212325536980161162443
    2. 登记端口号,数值为1024~49151。

  2. 客户端使用的端口号(短暂端口号),数值为49152~65535。

5.2 用户数据报协议UDP

5.2.1 UDP概述

主要特点:

  1. 无连接

  2. 尽最大努力交付

  3. 面向报文(UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界

    一次交付一个完整的报文。

    无论报文过长(IP层在传送时可能要进行分片)还是太短(IP数据报首部相对过长),都会降低IP层的效率。

  4. 没有拥塞控制(允许网络发生拥塞时丢失一些数据,但不允许数据有太大的时延)

  5. 支持一对一、一对多、多对一、多对多的交互通信

  6. 首部开销小(只有8字节,TCP要20字节)

在不影响应用的实时性的前提下,采用前向纠错或重传已丢失的报文的方法提高可靠性,减少数据的丢失。

5.2.2 UDP的首部格式

由四个字段组成,每个字段的长度都是两个字节

  1. 源端口,在需要对方回信时选用,不需要时可用全0
  2. 目的端口
  3. 长度,UDP用户数据报的长度,最小值8(仅有首部)
  4. 检验和,检验UDP用户数据报在传输中是否有错,有错就丢弃

如果接收方UDP发现收到的报文中的目的端口不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议ICMP发送“端口不可达”差错报文给发送方。

由于UDP是无连接的,所有不需要使用套接字建立连接(TCP需要)。

UDP的检验和是把首部和数据部分一起都检验;而IP数据报检验和只检验IP数据报首部。

检验和计算方法:

  1. 在UDP用户数据报之前增加12个字节的伪首部
  2. 在发送方,先把全0放如检验和字段,再把伪首部以及UDP用户数据报看成许多16位的字串接起来的。
  3. 若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全0字节(此字节不发送)。
  4. 然后按二进制反码计算出这些16位字的和。将此和的二进制反码写入检验和字段后,就发送这样的UDP用户数据报。
  5. 在接收方,把收到的UDP用户数据报连同伪首部(以及可能的填充全0字节)一起,按二进制反码求这些16位字的和。
  6. 若无差错,则结果为1;有差错就丢弃或上交给应用层,并附上差错的警告

UDP检验和,既检查UDP用户数据报的源端口号目的端口号以及UDP用户数据报数据部分,又检查IP数据报的源IP地址目的地址

5.3 传输控制协议TCP概述

5.3.1 TCP最主要特点

  1. 面向连接的运输层协议(使用TCP协议之前,必须建立TCP连接;传送数据完毕后,必须释放已经建立的TCP连接)

  2. 每一条TCP连接只能由两个端点(每一条TCP连接只能是点对点的)

  3. 提供可靠交付的服务(通过TCP连接传送的数据,无差错、不丢失、不重复,并且按需到达)

  4. 全双工通信

  5. 面向字节流

    TCP中的“流”指流入到进程或从进程流出的字节序列

    “面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流

    TCP和UDP在发送报文时所采用的方式完全不同。TCP并不关心应用进程一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥塞程度决定报文段应包含多少个字节(UDP发送的报文长度是应用进程给出的)。

5.3.2 TCP的连接

TCP把连接作为最基本的抽象

TCP连接的端口叫套接字插口。套接字:端口号拼接到IP地址即为套接字。
套 接 字 s o c k e t = ( I P 地 址 : 端 口 号 ) 套接字 socket = (IP地址:端口号) socket=(IP:)
每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。即:
T C P 连 接 : : = { s o c k e t 1 , s o c k e t 2 } = { ( I P 1 : p o r t 1 ) , ( I P 2 : p o r t 2 ) } TCP连接 ::=\lbrace socket_1 ,socket_2 \rbrace = \lbrace (IP_1:port_1),(IP_2:port_2) \rbrace TCP::={socket1,socket2}={(IP1:port1),(IP2:port2)}

5.4 可靠传输的工作原理

理想的传输条件:

  1. 传输信道不产生差错
  2. 不管发送方以多快的速度发送数据,接收方宋史来得及处理收到的数据

5.4.1 停止等待协议

  1. 无差错情况

    在这里插入图片描述

  2. 出现差错

    超时重传(设置超时计时器)。

    注意点:

    1. A在发送完一个分组后,必须暂时保留已发送的分组的副本(在发送超时重传时使用)。只有在收到相应的确认后才能清除暂时保留的分组副本。

    2. 分组和确认分组都必须进行编号

    3. 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些

      不确定因素:经过网络的不确定;产生时延(当前的拥塞情况)的不确定。

  3. 确认丢失和确认迟到

    (a)中,B需要采取两个行动:

    1. 丢弃这个重复的分组 M 1 M_1 M1,不向上层交付。
    2. 向A发送确认。(发送过不代表对方接收到)

    (b)中,A会收到重复的确认。对于重复的确认,收下后就丢弃。

    使用上述的确认和重传机制,就可以在不可靠的传输网络上实现可靠的通信。

    上述的可靠协议常称为自动重传请求ARQ,意思是重传的请求是自动进行的。接收方不需要请求发送方重传某个出错的分组。

  4. 信道利用率(计算

    信 道 利 用 率 U = T D T D + R T T + T A 信道利用率U = \frac{T_D}{T_D + RTT + T_A} U=TD+RTT+TATD

为了提高信道利用率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。流水线传输就是发送方可连续发送多个分组,不必没发完一个分组就停顿下来等待对方的确认。

5.4.2 连续ARQ协议

发送窗口的意义:位于发送窗口内的5个分组都可以连续发送出去,而不需要等待对方的确认。

发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。

接收方一般都是采用累计确认的方式。对按序到达的最后一个分组发送确认,表示到这个分组为止的所有分组都已正确收到了。

优点:容易实现,确认丢失也不必重传。

缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。

5.6 TCP可靠传输的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发送缓存与接收缓存的作用

发送缓存用来暂时存放:

  1. 发送应用程序传送给发送方 TCP 准备发送的数据
  2. TCP 已发送出但尚未收到确认的数据

接收缓存用来暂时存放:

  1. 按序到达的、但尚未被接收应用程序读取的数据;
  2. 不按序到达的数据。

注意点:

  1. 发送方的发送窗口和接收方的接收窗口不总是一样大
  2. 按序交付上层的应用进程
  3. 接收方必须有累计确认的功能

5.6.2 超时重传时间的选择(计算

往返时间RTT,TCP保留了RTT的一个加权平均往返时间 R T T S RTT_S RTTS(又称平滑的往返时间)。计算

每当第一次测量到RTT样本时, R T T S RTT_S RTTS值就取为所测量到的RTT样本值。但以后每测量到一个新的RTT样本,就按下式重新计算 R T T S RTT_S RTTS
新 的 R T T S = ( 1 − α ) × ( 旧 的 R T T S ) + α × ( 新 的 R T T 样 本 ) ( 0 ≤ α < 1 ) 新的RTT_S = (1 - α)\times(旧的RTT_S) + α\times(新的RTT样本)\quad\quad\quad(0 \leq α < 1) RTTS=(1α)×(RTTS)+α×(RTT)(0α<1)

若α很接近0,表示新的 R T T S RTT_S RTTS值和旧的 R T T S RTT_S RTTS的值相比变化不大,而对新的RTT样本影响不大(RTT值更新较慢)。

若α很接近1,表示新的 R T T S RTT_S RTTS值受新的RTT样本影响较大(RTT值更新较快)。

α推荐值为1/8,即0.125。

超时重传时间RTO,应略大于上面得出的加权平均往返时间 R T T S RTT_S RTTS计算
R T O = R T T S + 4 × R T T D RTO = RTT_S + 4 \times RTT_D RTO=RTTS+4×RTTD
R T T D RTT_D RTTD是RTT的偏差的加权平均值,它与 R T T S RTT_S RTTS和新的RTT样本只差有关。计算

当第一次测量时, R T T D RTT_D RTTD值取为测量到的RTT样本值的一半。但以后每测量到一个新的RTT样本,就按下式重新计算 R T T D RTT_D RTTD
新 的 R T T D = ( 1 − β ) × ( 旧 的 R T T D ) + β × ∣ R T T S − 新 的 R T T 样 本 ∣ ( β < 1 ) 新的RTT_D = (1 - β)\times(旧的RTT_D) + β\times|RTT_S - 新的RTT样本|\quad\quad\quad(β < 1) RTTD=(1β)×(RTTD)+β×RTTSRTT(β<1)
β推荐值为1/4,即0.25。

如何判断此确认报文段是对先发送的报文段的确认,还是对后来重传的报文段的确认?

若收到的确认是对重传报文段的确认,却被源主机当成是对原来的报文段的确认,则这样计算出的 R T T S RTT_S RTTS和超时重传时间RTO就会偏大。若后面再发送的报文段又是经过重传后才收到确认报文段,则按此方法得出的超时重传时间RTO就越来越长

同样,若收到的确认是对原来的报文段的确认,但被当成是对重传报文段的确认,则由此计算出的 R T T S RTT_S RTTS和RTO都会偏小。这就必然导致报文段过多地重传。这样就有可能使RTO越来越短

根据以上所述,Karn 提出了一个算法:在计算加权平均 R T T S RTT_S RTTS时,只要报文段重传了,就不采用其往返时间样本。这样得出的加权平均 R T T S RTT_S RTTS和RTO就较准确。

但是,这又引起新的问题。设想出现这样的情况:报文段的时延突然增大了很多。因此在原来得出的重传时间内,不会收到确认报文段。于是就重传报文段。但根据Karn算法,不考虑重传的报文段的往返时间样本。这样,超时重传时间就无法更新。

因此要对Karn算法进行修正。方法是:报文段每重传一次,就把超时重传时间RTO增大一些。典型的做法是取新的重传时间为旧的重传时间的2倍。当不再发生报文段的重传时,才根据上面给出的公式计算超时重传时间。实践证明,这种策略较为合理。

总之,Karn算法能够使运输层区分开有效的和无效的往返时间样本,从而改进了往返时间的估测,使计算结果更加合理。

5.6.3 选择确认SACK

选择确认:若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,只传送缺少数据而不重传已经正确到达接收方的数据。

我们用一个例子来说明选择确认(Selective ACK)的工作原理。TCP的接收方在接收对方发送过来的数据字节流的序号不连续,结果就形成了一些不连续的字节块。可以看出,序号11000收到了,但序号10011500没有收到。接下来的字节流又收到了,可是又缺少了3001~3500。再后面从序号4501起又没有收到。也就是说,接收方收到了和前面的字节流不连续的两个字节块。如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。

不连续的每个字节块都有两个边界:

  1. 左边界(指出字节块的第一个字节的序号)
  2. 右边界(右边界减1才是字节块中的最后一个序号,如3000 = 3001-1)

最多只能指明4个字节块(8个边界,每个边界4字节)还需要两个字节(一个指明SACK选项,一个指明这个选项要占多少字节)。

如果指明5个字节块(10个边界,每个边界4字节)还需要两个字节,42字节>40字节(选项长度的上限)。

大多数的实现还是重传所有未被确认的数据块。

5.7 TCP的流量控制

流量控制:让发送方的发送速率不要太快,要让接收方来得及接收。

滑动窗口机制进行流量控制。

下图假设每个报文段为100字节长。ACK:确认位ACK;ack:确认字段的值。

发送方的窗口不能超过接收方给出的接收窗口的数值。

TCP的窗口单位是字节,不是报文段。

现在我们考虑一种情况。在上图中,B向A发送了零窗口的报文段后不久,B的接收缓存又有了一些存储空间。于是B向A发送了 r w n d = 400 rwnd = 400 rwnd=400的报文段。然而这个报文段在传送过程中丢失了。A一直等待收到B发送的非零窗口的通知,而B也一直等待A发送的数据。如果没有其他措施,这种互相等待的死锁局面将一直延续下去。

为了解决这个问题,TCP为每一个连接设有一个持续计时器(persistence timer)。 只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。如果窗口仍然是零,那么收到这个报文段的一方就重新设置持续计时器。如果窗口不是零,那么死锁的僵局就可以打破了。

5.7.2 TCP的传输速效率

  1. 最大报文段长度MSS:只要缓存中存放的数据达到MSS字节时,就组成一个TCP报文段发送出去。
  2. 由发送方的应用进程指明要求发送报文段,即TCP支持的推送操作。
  3. 发送方的计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过MSS)发哦是那个出去。

在TCP 的实现中广泛使用 Nagle算法。算法如下:若发送应用进程把要发送的数据逐则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去, 同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。

Nagle 算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。这样做,就可以有效地提高网络的吞吐量

另一个问题叫做糊涂窗口综合征(silly window syndrome)[RFC 813],有时也会使TCP的性能变坏。设想一种情况: TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1个字节(这样就使接收缓存空间仅腾出1个字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报是40字节长)。接着,发送方又发来1个字节的数据(请注意,发送方发送的IP数据报是41字节长)。接收方发回确认,仍然将窗口设置为1个字节。这样进行下去,使网络的效率很低。

要解决这个问题,可以让接收方等待段时间, 使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。

上述两种方法可配合使用。使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了点小的空间就急忙把这个很小的窗 口大小信息通知给发送方。

5.8 TCP的拥塞控制

拥塞 ∑ 对 资 源 的 需 求 > 可 用 资 源 \sum 对资源的需求 > 可用资源 >

拥塞控制(全局性的过程)防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。

拥塞控制的前提:网络能够承受现有的网络负荷

流量控制往往是值点对点通信量的控制,是端到端的问题。

5.8.2 TCP的拥塞控制方法

  1. 慢开始和拥塞避免

    基于窗口:发送方让自己的发送窗口等于拥塞窗口crwd。

    判断网络拥塞的依据就是出现超时。

    慢开始算法思路:当主机开始发送数据时,由于并不清楚网络的负荷情况,所以如果立即把大量数据字节注入到网络,就有可能引起网络拥塞。经验证明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口(增大拥塞窗口数值)。

    旧的规定是这样的:在刚刚开始发送报文段时,先把初始拥塞窗口 cwnd 设置为1至2个发送方的最大报文段(SMSS)数值,但新的 RFC 5681 把初始拥塞窗口 cwnd 设置为不超过2至4个SMSS的数值,具体如下:

    • 若 SMSS > 2190字节,则设置初始拥塞窗口 cwnd = 2 x SMSS字节,且不得超过2个报文段
    • 若 1095字节 < SMSS ≤ 2190字节,则设置拥塞窗口 cwnd = 3 x SMSS字节,且不得超过3个报文段
    • 若 SMSS ≤ 1095字节,则设置初始拥塞窗口 cwnd = 4 x SMSS字节,且不得超过4个报文段

    慢开始规定,在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个 SMSS 的数值。更具体些,就是:
    拥 塞 窗 口 c w n d 每 次 的 增 加 量 = m i n ( N , S M S S ) 拥塞窗口 cwnd 每次的增加量 = min(N, SMSS) cwnd=min(N,SMSS)
    N是原先未被确认的、但现在刚收到的确认报文段所确认的字节数。

    虽然TCP是用字节数作为窗口大小的单位。但为了叙述方便,以下是用报文段的个数作为窗口大小的单位,这样可以使用较小的数字来阐明拥塞控制的原理。例:

    在一开始发送方先设置 cwnd = 1,发送第一个报文段M1,接收方收到后确认M1。发送方收到对M1的确认后,把 cwnd 从1增大到2,接着发送方发送M2和M3两个报文段。接收方收到后发回对M2和M3的确认。发送方每收到一个对新报文段的确认(重传的不算在内),就使发送方的拥塞窗口加1。因此,发送方在收到两个确认后,cwnd 就从2增大到4,并可发送M4~M7共4个报文段。可见使用慢开始算法后,每经过一个传输轮次,拥塞窗口就加倍

    传输轮次:一个传输轮次所经历的时间就是往返时间RTT。使用“传输轮次”是更加强调:把拥塞窗口 cwnd 所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。例如,拥塞窗口 cwnd 的大小是4个报文段,那么这时的往返时间RTT就是发送方连续发送4个报文段,并收到这4个报文段的确认,总共经历的时间。

    慢开始的慢并不是指 cwnd 的增长速率慢,而是指TCP开始发送报文段时先设置 cwnd = 1,使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大 cwnd。这当然比设置大的 cwnd 值一下子把许多报文段注入到网络中要“慢得多”。这对防止网络出现拥塞是一个非常好的方法。

    实际情况:在TCP的实际运行中,发送方只要收到一个对新报文段的确认,其拥塞窗口 cwnd 就立即加1,并可以立即发送新的报文段,而不需要等这个轮次中所有的确认都收到后,再发送新的报文段。

    为了防止拥塞窗口 cwnd 增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。慢开始门限 ssthresh 的用法如下:

    • 当 cwnd < ssthresh 时,使用上述的慢开始算法
    • 当 cwnd > ssthresh 时,使用下述的拥塞避免算法
    • 当 cwnd = ssthresh 时,即可使用慢开始算法,也可使用拥塞避免算法

    拥塞避免算法思路:当TCP连接进行初始化时,把拥塞窗口 cwnd 置为1。在本例中,慢开始门限的初始值设置为16个报文段,即 ssthresh = 16。在执行慢开始算法时,发送方每收到一个对新报文段的确认ACK,就把拥塞窗口值加1,然后开始下一轮的传输,拥塞窗口 cwnd 随着传输轮次按指数规律增长。当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh时(图中的点①),按线性规律增长。

    但拥塞避免并非完全能够避免拥塞,只是说控制为按线性规律增长,使网络比较不容易出现拥塞

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dAdu36K-1634824685365)(C:\Users\Flossysy\Desktop\满开始3.png)]当拥塞窗口 cwnd=24 时,网络出现了超时(图中的点②),发送方判断为网络拥塞。于是调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd=1,重新进入慢开始阶段。按照慢开始算法,发送方每收到一个对新报文段的确认ACK,就把拥塞窗口值加1。当拥塞窗口 cwnd = ssthresh = 12(图中的点③)时,改为执行拥塞避免算法,拥塞窗口按线性规律增大。

  2. 快重传

    如上图,当拥塞窗口 cwnd = 16(图中点④)时,出现了一个新的情况,就是发送方一连收到3个对同一个报文段的重复确认。有时个别报文段会在网络中丢失,但实际上网络并未发生拥塞。如果发送方迟迟收不到确认,就会产生超时,就会误认为网络发生了拥塞。这就导致发送方错误的启动慢开始,把拥塞窗口 cwnd 又设置为1,因而降低了传输效率。

    采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求接收方不要等待自己发送数据时才进行稍待确认,而是要立即发送确认,即使收到了失序的报文段,也要立即发出对已收到的报文段的重复确认。

    如下图所示,接收方收到了M1和M2后都分别及时发出了确认。现假定接收方没有收到M3,但却收到了M4。本来接收方可以什么也不做,但按照快重传算法,接收方必须立即发送对M2的重复确认,以便让发送方及早知道接收方没有收到报文段M3。发送方共收到了接收方的4个对M2的确认,其中后3个都是重复确认。快重传算法规定,发送方只要一连收到3个重复确认,就知道接收方确实没有收到报文段M3,应当立即进行重传。使用快重传可以使整个网络的吞吐量提高约20%。

  3. 快恢复

    因此,上上图中的点④,发送方知道现在只是丢失了个别的报文段。于是不启动慢开始,而是执行快恢复算法。这时,发送方调整门限值 ssthresh = cwnd / 2 = 8,同时设置拥塞窗口 cwnd = ssthresh = 8(图中的点⑤),并开始执行拥塞避免算法。

    有的快恢复实现是把快恢复开始时的拥塞窗口 cwnd 值在增大一些(增大3个报文段的长度),即等于新的 ssthresh + 3 x MSS。这样做的理由是:既然发送方收到3个重复的确认,就表明有3个分组已经离开了网络。这3个分组不再消耗网络的资源而是停留在接收方的缓存中(因为发出了3个重复的确认)。可见现在网络中并不是堆积了分组而是减少了3个分组,因此可以适当把拥塞窗口扩大一些。

从上上图可以看出,在拥塞避免阶段,拥塞窗口是按照线性规律增大的,这常称为加法增大AI (ditive Increase)。而一旦出现超时或3个重复的确认,就要把门限值设置为当前拥塞窗口值的一半,并大大减小拥塞窗口的数值。这常称为**“乘法减小”MD(Mtiplicivee Derease)。二者合在一起就是所谓的AIMD**算法。

根据以上所述,TCP的拥塞控制可以归纳为下面的流程图。例如,上上图没有说明在慢开始阶段如果出现了超时(即出现了网络拥塞)或出现3-ACK,发送方应采取什么措施。但从下面的流程图就可以很明确地知道发送方应采取的措施。

在这一节的开始我们就假定了接收方总是有足够大的缓存空间,因而发送窗口的大小由网络的拥塞程度来决定。但实际上接收方的缓存空间总是有限的。接收方根据自己的接收 能力设定了接收方窗口rwnd, 并把这个窗口值写入TCP首部中的窗口字段,传送给发送方。因此,接收方窗口又称为通知窗口(advertised window)。因此,从接收方对发送方的流量控制的角度考虑,发送方的发送窗口一定不能超过对方给出的接收方窗口值rwnd。

如果把本节所讨论的拥塞控制和接收方对发送方的流量控制一起考虑,那么很显然, 发送方的窗口的上限值应当取为接收方窗口 rwnd 和拥塞窗口 cwnd 这两个变量中较小的一个,也就是说:

发 送 方 窗 口 的 上 限 值 = M i n [ r w n d , c w n d ] 发送方窗口的上限值= Min [rwnd, cwnd] =Min[rwnd,cwnd]
当rwnd< cwnd时,是接收方的接收能力限制发送方窗口的最大值。

反之,当cwnd <rwnd时,则是网络的拥塞程度限制发送方窗口的最大值。

也就是说,rwnd 和ownd中数值较小的一个,控制了发送方发送数据的速率。

5.8.3 主动队列管理AQM

所谓“主动”就是不要等到路由器的队列长度已经达到最大值时才不得不丢弃后面到达的分组。这样就太被动了。

应当在队列长度达到某个值得警惕的数值时(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。这样就提醒了发送方放慢发送的速率,因而有可能使网络拥塞的程度减轻,甚至不出现网络拥塞。

AQM可以有不同实现方法,其中曾流行多年的就是随机早期检测RED (Random Early Detection)。 RED还有几个不同的名称,如Random Early Drop或Random Early Discard (随机早期丢弃)。

实现RED时需要使路由器维持两个参数,即队列长度最小门限最大门限。当每一个分组到达时,RED就按照规定的算法先计算当前的平均队列长度。

(1)若平均队列长度 < 最小门限,则把新到达的分组放入队列进行排队

(2)若平均队列长度 > 最大门限,则把新到达的分组丢弃

(3) 若平均队列长度在最小门限和最大门限之间,则按照某一丢弃概率 p p p把新到达的分组丢弃(这就体现了丢弃分组的随机性)。

由此可见,RED不是等到已经发生网络拥塞后才把所有在队列尾部的分组全部丢弃,而是在检测到网络拥塞的早期征兆时(即路由器的平均队列长度达到一一定数值时),就以概率p丢弃个别的分组,让拥塞控制只在个别的TCP连接上进行,因而避免发生全局性的拥塞控制。

5.9 TCP的运输连接管理

TCP是面向连接的协议,运输连接三个阶段:连接建立、数据传送、连接释放

运输连接的管理就是使运输连接的简历和释放都能正常地进行。

在TCP连接建立过程中要解决一下三个问题:

  1. 要使每一方都能够确知对方的存在: 所以需要三次握手。
  2. 要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)。
  3. 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配:建立TCB。

TCP连接的建立采用跟客户服务器模式。主动发起连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫做服务器

5.9.1 TCP的连接建立

TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段。下图画出了**三报文握手(three way (three message) handshake,以前译作“三次握手”)**建立连接的过程。

假定主机A运行的是TCP客户程序,而B运行TCP服务器程序。最初两端的TCP都处于CLOSED(关闭)状态。图中在主机下面的方框分别是TCP进程所处的状态。注意:本例中,A主动打开连接,而B被动打开连接。

一开始,B的TCP服务器进程先创建传输控制块TCB(存储了每一个连接中的一些重要信息,如:TCP连接表,指向发送和接收缓存的指针,指向重传队列的指针,当前的发送和接收序号,等等),准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。如有,即作出响应。

A的TCP客户进程也是首先创建传输控制块TCB。然后,在打算建立TCP连接时,向B发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x。TCP规定,**SYN报文段(即SYN=1的报文段)不能携带数据,但要消耗掉一个序号。**这时,TCP客户进程进入SYN-SENT(同步已发送)状态。

B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。注意:这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。

TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq=x+1。这是TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。

当B收到A的确认后,也进入ESTABLISHED状态。

为什么A最后还要发送一次确认?主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。

5.9.2 TCP的连接释放

数据传输结束后,此时A和B都处于ESTABLISHED状态。A先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。终止控制位FIN=1,其序号seq=u,他等于前面传输过的数据的最后一个字节的序号加1。这时A进入FIN-WAIT-1状态,等待B的确认。注意:TCP规定,FIN报文段即使不携带数据,它也消耗掉一个序号。

B接收到连接释放报文段后立即发出确认,确认号是ack=u+1,而这个报文段自己的序号seq=v,等于B前面已传输过的数据的最后一个字节的序号加1。然后B就进入CLOSE-WAIT(关闭等待)状态。此时从A到B这个方向的连接就释放了,这是的TCP连接处于半关闭状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收。也就是说,从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间。

A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段(在这之前还需要接受服务器发送的最后的数据)。

服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,其中必须使FIN=1。由于在半关闭状态,服务器可能又发送了一些数据,假定此时的序列号seq=w。B还必须重复上次已经发送过的确认号ack=u+1;此时服务器就进入LAST-ACK状态,等待客户端的确认。

客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号为seq=u+1,此时客户端就进入TIME-WAIT状态。注意此时TCP连接还没有释放,必须经过时间等待计时器设定的时间**2MSL(最长报文段寿命)**的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

而服务器在收到客户端发出的确认之后立即进入CLOSED状态,同样,撤销TCB之后,就结束了这次TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

为什么要等待2MSL的时间呢?

  1. 保证A最后发送的ACK报文段能够到达B。因为这个报文可能丢失,因此B会重传最后一个确认报文段,A再重新发送确认报文,并且重启计时器,直到A,B都能正常进入到CLOSED状态。
  2. 防止上面提到的“已失效的连接请求报文”出现在本连接中。2MSL这段时间内,这些连接请求报文就可能在网络中消失。

5.9.3 TCP的有限状态机

粗实线箭头表示对客户进程的正常变迁。

粗虚线箭头表示对服务器进程的正常变迁。

另一种细线箭头表示异常变迁。

上两张图左边客户进程从上到下的状态变迁,就是下图粗实线箭头所指的状态变迁。

上两张图右边服务器进程从上到下的状态变迁,就是下图粗虚线箭头所指的状态变迁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值