3. 传输层

本文详细介绍了互联网传输层的重要协议TCP和UDP,以及它们在数据传输、多路复用与分解、可靠性和拥塞控制方面的机制。TCP提供面向连接的、可靠的服务,包括三次握手建立连接,而UDP则是无连接的,提供简单高效但不可靠的数据传输。此外,文章还探讨了可靠数据传输的基本原理,如ARQ和选择重传协议,以及TCP的拥塞控制策略,如慢启动、拥塞避免和快速恢复等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 概述和运输层服务

传输层位于应用层和网络层之间,是分层的网络体系结构中重要的部分,该层为运行在不同主机上的应用进程提供直接的通信服务起着至关重要的作用。网络应用可以使用多种传输层协议,因特网有两种传输层协议,即TCP和UDP,不同的传输层协议提供不同的运输层服务

传输层协议为运行在不同端系统上的应用进程之间提供逻辑通信功能;应用层进程使用传输层提供的逻辑通信功能而无需考虑实现通信的物理基础设施的细节。运输层协议是在端系统中而不是在路由器中实现。

传输层接收来自应用层的报文并通过添加传输层首部以生成传输层报文段。在生成过程中可能会对来自应用层的报文加以分割;然后在发送端系统中,运输层会将这些报文段交给网络层;网络层将其封装成网络层分组,也被称为数据报,然后向目的地发送。路由器不会检查封装在数据报中的传输层报文段的字段;在接收端,网络层从数据报中抽取传输层报文段,并将其交给传输层,传输层接收到报文段后,使该报文段中的数据被接收进程所使用。

1.1 运输层和网络层的关系

在协议栈中,运输层刚好位于网络层之上。网络层提供了主机之间的逻辑通信,而运输层为运行在不同主机上的进程之间提供了逻辑通信。

在端系统中,传输层协议将来自应用进程的报文移动到网络边缘即网络层,反过来也从网络层接收这些报文段;传输层对报文段如何在网络核心传输并不做干涉;事实上中间路由器既不处理也不识别传输层加载应用层报文上的任何信息

1.2 因特网运输层概述

因特网为应用层提供了截然不同的两种传输层协议:UDP(用户数据报协议)它提供一种不可靠、无连接的服务;另一种是TCP,它提供可靠的,面向连接的服务,有拥塞控制,流量控制机制和连接建立过程。另外,将运输层分组称为报文段 ( segment) 。

简单了解一下网络层,网络层协议有一个名字即IP,即网际协议。IP为主机间提供逻辑通信,IP的服务模型为尽力而为交付服务(best-effort delivery service),它不保证报文段的交付、不保证报文段按序交付、不保证报文段中数据的完整性;即IP提供一种不可靠的服务;每台主机都需要有一个网络层地址,即IP地址。

2 多路复用与多路分解

运输层的多路复用与多路分解,也就是将由网络层提供的主机到主机交付服务延伸到为运行在主机上的应用程序提供进程到进程的交付服务。这种技术所有计算机网络都需要。

传输层和应用程序进程之间通过Socket(套接字) 关联,这样通过Socket就可以区别同一主机上的不同应用进程,从而传输层提供服务变为可能。传输层从同一台主机上的不同Socket接收数据的过程称为多路复用传输层向同一台主机上的不同Socket传输数据的过程称为多路分解。为了实现多路复用和多路分解,我们需要标志套接字,并将相关信息添加到报文段中。

每个套接字都有一个唯一的ID,被称为端口号;而在传输层接收到来自应用程序的分组并通过添加传输层首部而形成报文段的过程中,该端口号被写入;端口号大小在0-65535之间,其中0-1023属于周知端口号,它们为特定的Socket而拥有。

  • 无连接的多路复用与多路分解(UDP)

在创建Socket的时候,是由传输层为之分配端口号(1024-65535)。如果应用程序需要”周知协议“的服务器端,那开发者必须为其分配一个周知端口号。一个UDP套接字是由一个二元组全面标识的,该二元组包含一个目的IP地址和一个目的端口号

如果两个UDP报文段有不同的源1P地址或源端口号,但具有相同的目的IP地址和目的端口号,那么这两个报文段将通过相同的目的套接字被定向到相同的目的进程。

  • 面向连接的多路复用与多路分解(TCP)

TCP套接字是由一个四元组(源IP地址,源端口号,目的IP地址,目的端口号)来标识的。因此,当一个TCP报文段从网络到达一台主机时,该主机使用全部4个值来将报文段定向(分解)到相应的套接字。

两个具有不同源IP地址或者源端口号,但有相同的目的IP地址和目的端口号的TCP报文段将通过两个不同的Socket进入同一应用进程;这也表示,一个应用进程可以关联多个Socket,而一个Socket将只关联一个应用进程;常常,这样的对应关系是通过线程来实现的:一个进程有多个线程,而每个线程关联了一个Socket。

3 无连接运输:UDP

UDP只是做了运输协议能够做的最少工作。除了复用/分解功能及少量的差错检测外,它几乎没有对IP增加别的东西。如果开发者选择UDP,那么该应用程序就可能直接与IP打交道(如DNS)。TCP提供可靠数据传输和拥塞控制,但UDP对比TCP有以下好处:

  • 应用可更好地控制发送时间和速率
  • 无需建立连接 (减少延迟减少延迟)。这也可能是DNS使用UDP而不是TCP的主要原因,如果使用TCP的话,DNS服务将会慢很多。
  • 无需维护连接状态:TCP为了实现可靠数据传输和拥塞控制需要在端系统中维护一些参数,这些参数包括:接收和发送的缓存、拥塞控制参数、确认号和序号;这些参数信息都是必须的;而UDP因为不建立连接,所以自然也就不需要维护这些状态,这就减少了时空开销;
  • 分组首部更小:TCP有20字节的首部开销,而UDP只有8字节

这些应用程序使用了TCP作为其传输层协议:电子邮件、远程终端访问、Web、文件传输;这些应用通常使用UDP作为其传输层协议:远程文件服务器、网络管理(因为这里应用即便在网络处于拥塞的情况下仍要工作,所以UDP更为合适)、路由选择协议和名称转换(DNS);这些应用两个都有使用:流式多媒体、因特网电话等多媒体应用;这些应用对实时性的要求较高同时对可靠性的要求又不是很高,所以既可以使用UDP也可以使用TCP协议。

不过在UDP之上运行多媒体应用是有争议的,因为UDP没有拥塞控制协议,所以其对网络有很大的威胁性:大量的UDP流量将使网络过度拥塞而造成TCP连接几乎无法传输数据,并且因为网络拥塞,所以应用又有着较高的丢包率,而因为丢包率UDP很有可能继续发送数据,由此使得网络效率低下。

使用UDP仍然可以实现可靠数据传输,只不过这一部分功能需要在应用程序中自主开发;将可靠性直接构建于应用程序中,将使其既可以可靠地传输数据又可以避免受制于TCP的拥塞控制(传输速率的控制)。

3.1 UDP报文段结构

UDP首部只有4个字段,每个字段占用两个字节,分别是:源端口号、目的端口号、长度和校验和;长度字段指示了在 UDP 报文段中的字节数(首部加数据)。接收方使用检验和来检查在该报文段中是否出现了差错。

img

3.2 UDP检验和

UDP检验和提供了差错检测功能。这就是说,检验和用于确定当UDP报文段从源到达目的地移动时,其中的比特是否发生了改变。

一种常见的校验和的计算方法是:发送方将前三个字段做按位加运算,然后将其取反作为校验和;然后接收方对所有四个字段(每个字段16位)进行求和,如果没有出现差错,则最后的结果全是1,否则就表明出现了错误;出现错误的原因可能有:传输链路上数据受到干扰、数据存储在中间路由器的时候,出现了错误。

IP作为网络层协议,可以运行在任何第二层协议上,所以运输层提供差错检测也是必须的;UDP可以检测差错,但是无法恢复差错,能做的除了将其丢弃外,便是将其交给应用程序然后给出警告。

4 可靠数据传输原理

可靠数据传输为上层实体提供的服务抽象是:数据可以通过一套可靠的信道进行传输,借助于可靠信道,传输数据就不会受到损坏或者丢失;并且所有数据都可以按照其发送顺序进行交付。而这正是TCP向调用它的应用所提供的服务模型。

image-20230208105024015

实现这种抽象服务是可靠数据传输的责任,但是因为可靠数据传输的底层协议可能是不可靠的,所以这项任务有一点困难。

4.1 构造可靠数据传输协议

4.1.1 经完全可靠信道的可靠数据传输:rdt1.0

考虑最简单的情况,底层信道是完全可靠的。(实际上不合理)

(a)中的FSM定义了发送方的操作,(b)中的FSM定义了接收方的操作。发送方和接收方有各自的FSM,图中的箭头标识一种状态变迁。

在这里插入图片描述

4.1.2 经具有比特差错信道的可靠数据传输:rdt2.0

底层信道更为实际的模型是分组中的比特可能受损的模型。在分组的传输、传播或缓存的过程中,这种比特差错通常会岀现在网络的物理部件中。Rdt 2.0引入了以下的新机制:

  • 差错检测:一种机制,使得接收方检测到何时出现了比特差错
  • 接收方反馈控制信息:ACK / NAK。ACK(肯定确认):接收方显式地告知发送方分组已正确接收、接收方显式地告知发送方分组已正确接收。NAK(否定确认):接收方显式地告知发送方分组有错误
  • 重传:发送方收到NAK后,重传

这种基于重传机制的可靠数据传输协议称为自动重传请求(Automatic Repeat reQuest,AR)协议。

4.1.3 应对ACK/NAK破坏:rdt2.1

rdt 2.0 中有一个致命的缺陷,就是没有考虑到 ACK 和 NAK 分组受损的可能性。这里的难点在于,如果一个 ACK 或 NAK 分组受损,发送方无法知道接收方是否正确接收了上一块发送的数据 。

考虑ACK和NAK受损的个两可能性:

  • 增加足够的校验和比特
  • 当接受到模糊不清的ACK和NAK分组时,只需要重传当前数据分组。这引入了冗余分组

冗余分组的根本困难在于接收方不知道它上次所发送的ACK和NAK是否被发送方正确接收到。因此它无法事先知道接收到的分组是新的还是一次重传。解决这个新问题的一个简单的方法就是发送方给每个分组增加序列号,接收方丢弃重复分组。

与Rdt 2.0相比,Rdt 2.1变化如下:

发送方:

  • 为每个分组增加了序列号,因为是停等协议,两个序列号(0, 1)就够用
  • 需校验ACK/NAK消息是否发生错误
  • 状态数量翻倍:状态必须“记住”“当前”的分组序列号

接收方:

  • 需判断分组是否是重复,当前所处状态提供了期望收到分组的序列号
  • 注意:接收方无法知道ACK/NAK是否被发送方正确收到
4.1.4 无NAK消息协议:rdt2.2

我们真的需要两种确认消息(ACK + NAK)吗?与rdt2.1功能相同,但是只使用ACK,如何实现呢?

  • 接收方通过ACK告知最后一个被正确接收的分组,在ACK消息中显式地加入被确认分组的序列号
  • 发送方收到重复ACK 之后,重传当前分组
4.1.5 经具有比特差错的丢包信道的可靠数据传输:rdt3.0

除了比特受损外,底层信道还会丢包,协议现在必须处理另外两个关注的问题:怎样检测丢包以及发生丢包后该做些什么。rdt2.2使用“校验和 + 序列号 + ACK + 重传”就不够了,还需要增加新的协议机制。

在 rdt 3.0 中,丢包的问题让发送方解决。不管是发送的分组丢失,还是接收方返回的确认分组丢失,只要在经过一定的时延后,让发送方重发该分组即可。

  • 需要一个定时器,判定可能发生了丢包。如果在这个时间内没有收到ACK,就进行重传
  • 由此产生的冗余数据分组则由接收方通过序号处理。为了实现基于时间的重传机制,需要一个倒计数定时器(countdown timer),在 一个给定的时间量过期后,可中断发送方
  • 如果分组或ACK只是延迟而不是丢了,重传会产生重复,序列号机制能够处理,接收方需在ACK中显式告知所确认的分组

因为分组序号在 0 和 1 之间交替,因此 rdt 3.0 有时被称为比特交替协议

4.2 流水线可靠数据传输协议

rdt 3.0的核心问题在于他是一个停等协议。rdt 3.0 是一个功能正确的协议,但是由于它是一个停等协议,大部分的时间都浪费在等待确认上面,所以性能不好。解决这种特殊性能问题的一个简单的方法是:不使用停等方式运行,允许发送方发送多个分组而无需等待确认。这种技术被称为流水线

要使用流水线技术,则须:

  • 增加序号范围。因为要传送多个分组,而每个传输中的分组必须有一个单独的序号。
  • 协议的发送方和接收方两端必须能缓存多个分组。发送方至少得能缓存那些已发送但未确认的分组,而接收方或许也需要缓存那些已经正确接收的分组。
  • 所需序号的范围和对缓冲的要求取决于数据传输协议如何处理丢失、损坏及延时过大的分组。

4.3 回退N步(GBN)

在回退N步(GBN)协议中,允许发送方发送多个分组(当有多个分组可用时)而不需等待确认,但它也受限于在流水线中未确认的分组数不能超过某个最大允许数。N 被称为窗口长度(window size),GBN 协议也常被称为滑动窗口协议(sliding-window protocol)。

在回退N步中,发送方维护一个N——窗口大小和一个base——发送方期待收到的最小待确认分组序号,同样也是窗口的起点,还有一个next Sequence变量,表示上层需要发送分组时,可以使用的序号。当发送方收到确认号为base的确认分组后就会向前移动窗口

在这里插入图片描述

  • 0-base-1,这一部分的分组是已发送且收到接收方确认的分组
  • base~next Sequence-1这一部分的分组是已发送但是尚未收到确认的,其中base是尚未收到确认的最小序号
  • next-1~base+N-1表示当前发送方可以使用的序号,表示一种发送能力

GBN发送方需要响应的事件有:上层调用、收到ACK、超时事件

  • 上层调用:检查next Sequence是否在窗口之内,如果在,这说明发送方还有发送能力,发送
  • 收到ACK:回退N步策略对序号为n的分组采取累积确认的方式,即当收到序号为n的ACK时,表明序号小于等于n的分组全部到位
  • 超时事件:如果发生超时事件,那么发送方会重发所有已发送但是未确认的分组,即分组号在base和next sequence-1之间的所有分组;这也是为什么叫“回退N步”,如果收到一个ACK,则定时器会重行启动;如果没有待确认的分组,定时器将被终止

在接收方,如果到达分组的序号为n且该分组是按序到达,那么发送ACK,这就导致发送方移动窗口;如果不是按序到达,那么接收方丢弃所有失序分组;丢弃一个正确接收的失序分组可能会导致更多的重传。

4.4 选择重传(SR)

GBN 的缺点:单个分组的差错就能够引起 GBN 重传大量分组,许多分组根本没有必要重传。 选择重传(SR)协议通过让发送方仅重传那些它怀疑在接收方出错(即丢失或受损)的分组而避免了不必要的重传。

SR 发送方的事件和动作:

  • 从上层接收数据: 检查下一个可用于该分组的序号,若在发送方的窗口内,则将数据打包发送。
  • 超时: 定时器再次用来防止丢失分组。但是现在每个分组必须得有单独的定时器。
  • 收到 ACK:倘若该分组序号在窗口内,则 SR 发送方将那个被确认的分组标记为已接收。如果该分组的序号等于send_base,则窗口基序号向前移动到具有最小序号的未确认分组处。如果窗口移动了并且该序号落在窗口内的未发送分组,则发送这些分组。

SR接收方的事件与动作:

  • 序号在 [rcv_base,rcv_base + N -1] 内的分组被正确接收。在此情况下,收到的分组落在接收方的窗口内,一个选择 ACK 被回送给发送方。如果该分组以前没收到过,则缓存该分组。如果该分组的序号等于接收窗口的基序号,则该分组及以前缓存的序号连续的分组交付给上层。
  • 序号在 [rcv_base - N,rcv_base - 1] 内的分组被正确接收。产生一个 ACK,即使该分组是接收方以前已确认过的分组。
  • 其他情况:忽略该分组

5 面向连接的TCP

5.1 TCP连接

TCP协议是面向连接的协议。TCP只运行在端系统之上,而不在中间的网络元素(路由器和链路层交换机)中运行,所以中间的网络元素不会维持TCP连接状态。更像一种状态而不是物理的、实际的连接。

TCP提供全双工服务,并且是点对点的,数据从A到B的同时,也能从B到A;TCP协议无法提供“多播”服务,一条TCP连接只关联一个发送方和接收方(当然,发送方也是接收方)

TCP建立过程称为“三次握手”,前两次报文段不承载“有效负载”,第三次握手报文段是可以装载“有效负载”。

这个过程是这样的:通信的发起方首先发送一个特殊的TCP报文段给接收方,这是第一次握手;接收方收到该报文段后,对该报文段进行响应,此为第二次握手;发送方接收到响应报文段后,发送第三个报文段,其中包含了有效负载;因为TCP建立的过程,一共发生了三次握手,所以该过程也被称为三次握手

当TCP连接建立后,两个应用进程就可以发送数据了。应用程序将要发送的数据通过Socket传递给TCP,TCP将数据引导到该连接的发送缓存,发送缓存大小是在三次握手的过程中确定的;之后TCP将时不时从该缓存中拿出数据进行发送。TCP连接的每一端都有发送和接收缓存。

TCP每次可以从缓存中发送的最大数据长度称为于最大报文段长度(Maximum Segment Size,MSS)。一般来说,MSS+TCP/IP首部的长度要小于等于链路的最大传输单元(Maximum Transmission Unit,MTU)。而以太网和PPP的MTU都等于1500字节,TCP/IP的首部通常为40字节,所以MSS一般来说为1460字节。

TCP为每块客户数据配上一个TCP首部,从而形成多个TCP报文段(TCP segment)。 这些报文段被下传给网络层,网络层将其分别封装在网络层IP数据报中。然后这些IP数 据报被发送到网络中。当TCP在另一端接收到一个报文段后,该报文段的数据就被放入该 TCP连接的接收缓存中。

在这里插入图片描述

5.2 TCP报文段结构

TCP报文段结构,从整体上来说由首部+数据字段组成;其中数据字段来自应用层,其长度不能大于MSS;首部的常规长度为20字节,但是值得注意的是,TCP首部是可变长的;TCP首部是以32比特为单位组织的,其结构组成如下图:

image-20230209104053810
  • 源端口号和目的端口号:这两个数据用于TCP的多路复用和多路分解;分别为16位;

  • 序号:该数据被用于实现可靠数据传输之按序到达,在一个TCP连接中,算是一个报文段的id,同时该id还指示了其所承载的数据的位置信息;占32位;

  • 确认号:TCP被称为提供累积确认,确认号表示期望收到的下一字节的序号

  • 首部长度:以32比特的字为单位的TCP首部长度。

  • 选项字段:该字段用于在发送方和接收方之间协商MSS的大小,在高速网络环境下,也可用于调节窗口大小

  • 标记字段:
    (1)ACK位表示确认号字段的里的值是否有效,如果ACK被置位,那么该报文段就对确认号所指示的报文段进行了确认
    (2)RST、SYN和FIN位用于TCP的连接和拆除
    (3)PSH被置位时,指示接收方应该立即将数据交给上层
    (4)URG被置位时表示报文段里存在着发送端的上层实体置为紧急的数据;紧急数据的最后一个字节由16位紧急指针指出。当紧急数据存在并且给出了指向紧急数据尾指针时,TCP必须通知接收端的上层实体

​ 实际上,PSH、URG和紧急数据指针在实践中并没有被使用;标记字段一共6比特;

5.3 往返时间的估计与超时

(1) 估计往返时间

TCP使用一种Sample RTT的方法来估计RTT。Sample RTT就是从某报文段发出到收到对该报文段的确认之间的时间量。大多数TCP的实现是在某个时刻做一个Sample RTT测试。TCP并不为已经重发的报文段做Sample RTT测试,它只为传输一次的报文段测量Sample RTT。

TCP 维持一个 SampleRTT 均值(称为EstimatedRTT),一旦获得一个新SampleRTT时,TCP 就会根据下列公式来更新 Estimated RTT,这种方法也被称为指数加权移动平均:
E s t i m a t e d R T T = ( 1 − a ) E s t i m a t e d R T T + a ∗ S a m p l e Estimated RTT=(1-a)Estimated RTT+a*Sample EstimatedRTT=(1a)EstimatedRTT+aSample
测量RTT的变化也是有价值的。DevRTT用于估算SampleRTT偏离EstimatedRTT的程度。
D e v R T T = ( 1 − b ) D e v R T T + b ∗ ∣ S a m p l e R T T − E s t i m a t e d R T T ∣ DevRTT =(1-b)DevRTT+b*|Sample RTT-Estimated RTT| DevRTT=(1b)DevRTT+bSampleRTTEstimatedRTT
其中b的推荐值为0.25;当Sample RTT变化较大的时候,DevRTT的值较大,当Sample RTT变化较小的时候,DevRTT就较小。

(2)设置和管理重传超时间隔

TCP是如何考虑超时时间的呢?该时间因略大于测量的RTT,过小容易引起不必要的重传,过大时网络对于报文段丢失情况的反应就会变慢;最后TCP采用了如下计算方式:
T i m e o u t   I n t e r v a l = E s t i m a t e d R T T + 4 ∗ D e v R T T Timeout \ Interval=Estimated RTT+4*Dev RTT Timeout Interval=EstimatedRTT+4DevRTT
同时,当出现超时后,Timeout lnterval值将加倍,以免即将被确认的后继报文段过早出现超时。当然,只要收到报文段并更新EstimatedRTT,就使用上述公式再次计算Timeoutinterval

5.4 可靠数据传输

IP协议提供的是尽力而为的服务:不保证不丢失、不保证按序到达、不保证没有损坏。TCP协议在IP协议之上,提供可靠数据传输,从而保证一个进程从其相关联的缓存中读取的数据和另一端进程发送的数据是一致的;TCP使用超时重传和冗余确认技术来处理超时、丢失等情况;使用确认、序号等技术来保证按序到达;使用校验和来检验是否报文段在传输过程中是否发生了错误。

TCP 发送方有三个与发送和重传有关的事件:

  • 从上层应用程序接收数据
  • 定时器,TCP通过重传引起超时的报文段来响应超时事件。然后TCP重启定时器
  • 收到 ACK,确认报文段被接收

(1)超时时间加倍

在大多数TCP实现中,当发生超时事件时,直接将超时时间设置为原来的两倍;然而,每当定时器在另两个事件(收到ACK和接收到上层应用数据)发生时,新的超时时间将由 Estimated RTT和 Dev RTT 两个值计算出来

(2)快速重传

一旦收到 3 个冗余 ACK,TCP 就执行快速重传(fast retransmit)。如果发送方收到冗余ACK,说明有多个报文段到达了接收端,但不是接收端所期望的——这意味着,很有可能发生了丢失。所以发送方可以在定时器过时之前快速重传所丢失的报文段。

(3)回退N步或选择重传

TCP 确认是累积式的,TCP 发送方仅需维持已发送过但未被确认的字节的最小序号(SendBase)和下一个要发送的字节的序号(NextSeqNum)。在这种意义下,TCP 看起来更像一个 GBN 风格的协议。但是 TCP 和 GBN 协议之间有着一些显著的区别。许多 TCP 实现会将正确接收但失序的报文段缓存起来。

对TCP提出的一种修改意见是所谓的选择确认——即接收方对失序到达的分组也会确认,当该机制和重传机制相结合使得TCP更像选择重传,于是TCP的差错恢复协议最好被分类为GBN和SR协议的混合体。

5.5 流量控制

TCP为它的应用程序提供了流量控制服务(flow control service)以消除发送方使接收 方缓存溢岀的可能性。流量控制因此是一个速度匹配服务,即发送方的发送速率接收方应用程序的读取速率相匹配,而不让对方发生数据溢出。

TCP发送方也可能因为IP网络的拥塞而被遏制;这种形式的发送方的控制被称为拥塞控制,即使流量控制和拥塞控制采取的动作非常相似(对发送方的遏制),但是它们显然是针对完全不同的原因而采取的措施。

TCP通过让发送方维护一个称为接收窗口(receive window)的变量来提供流量控制。通俗地说,接收窗口用于给发送方一个指示一一该接收方还有多少可用的缓存空间。因为TCP是全双工通信,在连接两端的发送方都各自维护一个接收窗口。

同样,再TCP连接的两端,各自维护着相关的变量:last Sent、last Acked;在发送方,这两个变量之间的分组就是已经发送但是尚未确认的分组;而在接收方,last Read表示应用进程下一次读取的数据,last Revd表示最后纳入缓存的报文段编号;通过这些变量以及报文段首部中窗口大小字段,我们就可以对发送速度做一些控制:在发送方last Sent-last Acked应该小于等于接收方的窗口大小;在接收端A=last Received-last Read就是已经使用的空间大小,所以窗口大小=buffer-A

5.6 TCP连接管理

(1)TCP三次握手

一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态手

第一个报文(SYN报文):客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的"序号"字段中,把 SYN 标志位置为 1 ,表示 SYN 报文。把SYN报文发给服务端表示向服务端发起连接,之后客户端处于 SYN-SENT 状态。

第二个报文(SYN+ACK):服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的"序号"字段中,其次把 TCP 首部的"确认号"字段填入 client_isn + 1,把 SYN 和 ACK 标志位置为 1,发给客户端,服务端处于 SYN-RCVD 状态。

第三个报文(ACK):客户端还要回应一个应答报文,应答报文 TCP 首部 ACK 标志位置为 1 ,其次“确认号”字段填入 server_isn + 1 发送给服务端,客户端处于 ESTABLISHED 状态。服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态。

第三次握手可以携带数据,前两次握手不可以携带数据

image-20230209115301205

为什么连接建立需要三次握手,而不是两次握手?防止失效的连接请求报文段被服务端接收,从而产生错误(主要原因)。同步双方的初始序列号、避免资源浪费

(2)TCP四次挥手

TCP连接的释放一共需要四步,因此称为『四次挥手』。我们知道,TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。

image-20230209120202626

第一次挥手

若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:
FIN=1,seq=u。此时,A将进入FIN-WAIT-1状态。

PS1:FIN=1表示该报文段是一个连接释放请求。
PS2:seq=u,u-1是A向B发送的最后一个字节的序号。

第二次挥手

B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。此时B进入CLOSE-WAIT状态,并向A发送连接释放的应答,其报文头包含:
ACK=1,seq=v,ack=u+1。

PS1:ACK=1:除TCP连接请求报文段以外,TCP通信过程中所有数据报的ACK都为1,表示应答。
PS2:seq=v,v-1是B向A发送的最后一个字节的序号。
PS3:ack=u+1表示希望收到从第u+1个字节开始的报文段,并且已经成功接收了前u个字节。
A收到该应答,进入FIN-WAIT-2状态,等待B发送连接释放请求。

第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。

第三次挥手

当B向A发完所有数据后,向A发送连接释放请求,请求头:FIN=1,ACK=1,seq=w,ack=u+1。B便进入LAST-ACK状态。

第四次挥手

A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。
为什么A要先进入TIME-WAIT状态,等待时间后才进入CLOSED状态?为了保证B能收到A的确认应答。
若A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,因此B永远无法正常关闭。

6 拥塞控制原理

拥塞(Congestion)非正式定义:“太多发送主机发送了太多数据或者发送速度太快
,以至于网络无法处理”。表现为分组丢失(路由器缓存溢出)和分组延迟过大(在路由器缓存中排队)

6.1 拥塞原因与代价

计算机网络拥塞的原因是因为网络中的分组太多,而链路带宽和路由器缓存容量都是有限的

  • 当分组的到达速率接近链路容量时,分组将经历巨大的排队时延;
  • 发送方必须执行重传已补偿因为缓存溢出而丢弃的分组
  • 发送方遇到大时延时所进行的不必要重传会引起路由器利用其链路带宽来转发不必要的分组副本。
  • 当一个分组沿着一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量最终被浪费掉了;

6.2 拥塞控制方法

拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收。

总体来说,我们可以根据网络层是否为传输层拥塞控制提供了显式帮助来区分拥塞控制方法:端到端拥塞控制和网络辅助拥塞控制

  • 端到端拥塞控制:网络层不需要显式的提供支持,端系统通过观察loss,delay等网络行为判断是否发生拥塞,TCP采取这种方法
  • 网络辅助的拥塞控制:路由器向发送方显式地反馈网络拥塞信息,简单的拥塞指示(1bit):SNA,DECbit,TCP/IP ECN,ATM,指示发送方应该采取何种速率

7 TCP拥塞控制原理

我们将TCP发送方的丢包事件定义为:要么超时,要么收到接收方的3个冗余ACK;

TCP拥塞控制算法包含三个主要部分:慢启动、拥塞避免、快速恢复;慢启动和拥塞控制是TCP的强制部分;两者的差异在于对收到的ACK做出反应时增加拥塞窗口(cwnd)长度的方式;快速恢复是推荐部分,对于TCP发送方并非是必须的。

我们假设,发送方可以在RTT时间范围内连续发送cwnd个字节的数据,所以发送速率即为cwnd/RTT;发送方通过调整窗口大小来对发送数据的速率加以控制

(1)慢启动

TCP连接在开始的时候,其cwnd常设置为一个MSS,然后在慢启动状态每收到一个ACK,cwnd就增加一个MSS;这样的话,在慢启动阶段,发送速率是指数增加的(1,2,4,8…)

何时结束这种指数增长?有三种情况:发送了超时、发生了冗余ACK以及cwnd达到ssthresh。ssthresh是慢启动阈值的速记;在慢启动阶段,如果发生了超时事件,那么ssthresh就被设置为当前cwnd的一半,然后将cwnd置为1;当cwnd逐步增加到ssthresh时,再翻倍增加cwnd就有一点鲁莽了,所以此时TCP结束慢启动,进入拥塞避免模式。在拥塞避免模式里,TCP将更谨慎地增加cwnd;如果收到冗余ACK,那么TCP会做一次快速重传,然后进入快速恢复阶段

(2)拥塞避免

一旦进入拥塞避免状态,cwnd的值大约是上次遇到拥塞时的一半,所以TCP在每个RTT中,只将cwnd增加一个1个MSS大小;也就是说在拥塞避免阶段,cwnd是线性增加的;

当出现超时时,TCP将cwnd设置为1,然后将ssthresh更新为cwnd的一半;当收到冗余ACK时,TCP将cwnd减半,然后将ssthresh置为cwnd值的一半,并且进入快速恢复状态;

(3)快速恢复

在快速恢复阶段,对于引起TCP进入该状态的缺失报文段,每收到一个ACK,cwnd增加一个MSS;最终,当对丢失报文段的一个ACK到达时,TCP降低cwnd后进入拥塞避免状态;如果出现超时事件,快速恢复在执行如同慢启动和拥塞避免中相同动作后,进入慢启动状态。

当多条连接共享一条瓶颈链路时,那些具有较小RTT的连接能够在链路空闲时更快的抢到可用带宽(即较快的打开其拥塞窗口),因而将比那些具有较大RTT的连接享用更高的吞吐量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

⁠脱欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值