运输层功能详解

本文深入探讨了运输层的功能,包括TCP和UDP的区别。TCP提供面向连接、可靠的服务,而UDP则是无连接、不可靠的。详细介绍了TCP的连接建立与释放、可靠传输原理如停止等待协议、滑动窗口协议,以及流量控制和拥塞控制机制。同时,简述了UDP的首部格式和特点,强调了其在实时应用中的优势。

1.概述

  • 作用:运输层为它上面的应用层提供通信服务。
  • 在OSI七层参考模型中,运输层是面向通信的最高层,也是用户功能的最底层。
  • 传输层两大重要的功能:复用 和 分用。
    1.复用在发送端,多个应用进程公用一个传输层
    2.分用在接收端,传输层会根据端口号将数据分派给不同的应用进程
  • 和网络层的区别:
    1.网络层为不同主机提供通信服务,而传输层为不同主机的不同应用提供通信服务。
    2.网络层只对报文头部进行差错检测,而传输层对整个报文进行差错检测。

当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的,但这种逻辑通信信道就相当于一条全双工的可靠信道。但当运输层采用无连接的UDP协议时,这种逻辑信道任然是一条不可靠信道。

2. 用户数据报协议UDP

2.1 UDP概述

  1. UDP只在IP数据报服务的基础上增加了少量的功能:复用与分用、对整个报文的差错检测。
  2. UDP是无连接的
    通信前不需要建立连接,通信结束也无需释放连接。
  3. UDP是不可靠的
    它是尽最大努力交付,不能确保每一个数据报都送达。
  4. UDP是面向报文的
    所谓 面向报文 就是指:UDP数据传输的单位是报文,且不会对数据作任何 拆分 和 拼接 操作。
    在发送端,应用程序给传输层的UDP什么样的数据,UDP不会对数据进行切分,只增加一个UDP头并交给网络层。
    在接收端,UDP收到网络层的数据报后,去除IP数据报头部后遍交给应用层,不会作任何拼接操作。
  5. UDP没有拥塞控制
    UDP始终以恒定的速率发送数据,并不会根据网络拥塞情况对发送速率作调整。这种方式有利有弊。
    弊端:网络拥塞时有些报文可能会丢失,因此UDP不可靠。
    优点:有些使用场景允许报文丢失,如:直播、语音通话,但对实时性要求很高,此时UDP还是很有用武之地的。
  6. UDP支持一对一、一对多、多对多、多对一通信
    而TCP只支持一对一通信。
  7. UDP首部开销小,只有8字节。
    而TCP头部至少由20字节,相比于TCP要高效很多。

2.2 UDP的首部格式

在这里插入图片描述

  • 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。
  • 目的端口:目的端口号。这在终点交付报文时必须要使用到。
  • 长度: UDP用户数据报的长度,其最小值是8(仅有首部)。
  • 校验和:检测UDP用户数据报在传输中是否有错。有错就丢弃。
    在这里插入图片描述
    伪首部
    在 TCP 的分段或 UDP 的数据报格式中,在数据报首部前面增加源 IP 地址、目的 IP 地址、IP 分组的协议字段、TCP 或 UDP 数据报的总长度等共12字节,所构成的扩展首部结构。此伪首部是一个临时的结构,它既不向上也不向下传递,仅仅只是为了保证可以校验套接字的正确性。

3. 传输控制协议TCP

3.1 TCP最主要的特点

  1. TCP是面向连接
    通信前需要建立连接,通信结束需要释放连接。
  2. 每一条TCP连接只能有两个端点
    TCP只能提供点到点的通信,而UDP可以任意方式的通信。
  3. TCP提供可靠交付的服务
    可靠指的是:TCP发送的数据无重复、无丢失、无错误、与发送端顺序一致。
  4. TCP提供全双工通信
    全双工通信指的是:TCP的两端既可以作为发送端,也可以作为接收端。
  5. TCP是面向字节流
    面向字节流指的是:TCP以字节为单位。虽然传输的过程中数据被划分成一个个数据报 ,但这只是为了方便传输,接收端最终接受到的数据将与发送端的数据一模一样。

3.2 TCP的连接

  • TCP连接就是由协议软件所提供的一种抽象。表示一条可通信的链路。每条TCP连接有且仅有两个端点,表示通信的双方。且双发在任意时刻都可以作为发送者和接收者。
  • TCP连接的端点叫做套接字或插口。
    套接字 socket =(IP地址:端口号)
    因此,TCP连接 ::=(套接字1,套接字2)={(IP1:端口号1),(IP2:端口号2)}

3.3 可靠传输的工作原理

TCP的可靠性表现在:它向应用层提供的数据无差错的、有序的无丢失的,简单的说就是:TCP最终递交给应用层的数据和发送者发送的数据是一模一样的

TCP采用了流量控制拥塞控制连续ARQ等技术来保证它的可靠性

当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速度。这样一来,本来是不可靠的传输信道就能够实现可靠传输了。

3.3.1 停止等待协议(ARQ协议)

TCP保证其可靠性采用的是更为复杂的滑动窗口协议,但停止等待协议是它的简化版,为了方便理解,这里先介绍停止等待协议。
AQR协议

ARQ(Automatic Repeat reQuest)自动重传请求。
顾名思义,当请求失败时它会自动重传,直到请求被正确接收为止。这种机制保证了每个分组都能被正确接收。停止等待协议是一种ARQ协议。

停止等待协议的原理

  • 无差错的情况
    A向B每发送一个分组,都要停止发送,等待B的确认应答;A只有收到了B的确认应答后才能发送下一个分组。

  • 分组丢失和出现差错的情况
    发送者拥有超时计时器。每发送一个分组便会启动超时计时器,等待B的应答。若超时仍未收到应答,则A会重发刚才的分组。
    分组出现差错:若B收到分组,但通过检查和字段发现分组在运输途中出现差错,它会直接丢弃该分组,并且不会有任何其他动作。A超时后便会重新发送该分组,直到B正确接收为止。
    分组丢失:若分组在途中丢失,B并没有收到分组,因此也不会有任何响应。当A超时后也会重传分组,直到正确接收该分组的应答为止。
    综上所述:当分组丢失 或 出现差错 的情况下,A都会超时重传分组。

  • 应答丢失 和 确认迟到 的情况
    TCP会给每个字节都打上序号,用于判断该分组是否已经接收。
    应答丢失:若B正确收到分组,并已经返回应答,但应答在返回途中丢失了。此时A也收不到应答,从而超时重传。紧接着B又收到了该分组。接收者根据序号来判断当前收到的分组是否已经接收,若已接收则直接丢弃,并补上一个确认应答。
    确认迟到:若由于网络拥塞,A迟迟收不到B发送的应答,因此会超时重传。B收到该分组后,发现已经接收,便丢弃该分组,并向A补上确认应答。A收到应答后便继续发送下一个分组。但经过了很长时间后,那个失效的应答最终抵达了A,此时A可根据序号判断该分组已经接收,此时只需简单丢弃即可。

停止等待协议的注意点

  • 每发送完一个分组,该分组必须被保留,直到收到确认应答为止。
  • 必须给每个分组进行编号。以便按序接收,并判断该分组是否已被接收。
  • 必须设置超时计时器。每发送一个分组就要启动计时器,超时就要重发分组。
  • 计时器的超时时间要大于应答的平均返回时间,否则会出现很多不必要的重传,降低传输效率。但超时时间也不能太长。

3.3.2 滑动窗口协议(连续ARQ协议)

  1. 连续ARQ协议
    在ARQ协议发送者每次只能发送一个分组,在应答到来前必须等待。而连续ARQ协议的发送者拥有一个发送窗口,发送者可以在没有得到应答的情况下连续发送窗口中的分组。这样降低了等待时间,提高了传输效率。

  2. 累计确认
    在连续ARQ协议中,接收者也有个接收窗口,接收者并不需要每收到一个分组就返回一个应答,可以连续收到分组之后统一返回一个应答。这样能节省流量

TCP头部的ack字段就是用来累计确认,它表示已经确认的字节序号+1,也表示期望发送者发送的下一个分组的起始字节号。下面会介绍TCP头部报文段。

在这里插入图片描述
发送窗口的大小由接收窗口的剩余大小决定。接收者会把当前接收窗口的剩余大小写入应答TCP报文段的头部,发送者收到应答后根据该值和当前网络拥塞情况设置发送窗口的大小。发送窗口的大小是不断变化的。
发送窗口由三个指针构成:

  • p1指向发送窗口的后沿,它后面的字节表示已经发送且已收到应答。
  • p2指向尚未发送的第一个字节。
    p1-p2间的字节表示已经发送,但还没收到确认应答。这部分的字节仍需保留,因为可能还要超时重发。
    p2-p3间的字节表示可以发送,但还没有发送的字节。
  • p3指向发送窗口的前沿,它前面的字节尚未发送,且不允许发送。

接收者收到的字节会存入接收窗口,接收者会对已经正确接收的有序字节进行累计确认,发送完确认应答后,接收窗口就可以向前移动指定字节。
如果某些字节并未按序收到,接收者只会确认最后一个有序的字节,从而乱序的字节就会被重新发送。

连续ARQ的注意点

  1. 同一时刻发送窗口的大小并不一定和接收窗口一样大。
    虽然发送窗口的大小是根据接收窗口的大小来设定的,但应答在网络中传输是有时间的,有可能t1时间接收窗口大小为m,但当确认应答抵达发送者时,接收窗口的大小已经发生了变化。
    此外发送窗口的大小还随网络拥塞情况影响。当网络出现拥塞时,发送窗口将被调小。

  2. TCP标准并未规定未按序到达的字节的处理方式。但TCP一般都会缓存这些字节,等缺少的字节到达后再交给应用层处理。这比直接丢弃乱序的字节要节约带宽。

  3. TCP标准规定接收方必须要有累计确认功能。接收方可以对多个TCP报文段同时确认,但不能拖太长时间,一般是0.5S以内。
    此外,TCP允许接收者在有数据要发送的时候捎带上确认应答。但这种情况一般较少,因为一般很少有两个方向都要发送数据的情况。

3.3.3 流量控制

什么是流量控制?
如果发送者发送过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制

流量控制的目的?
流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。

如何实现流量控制?
由滑动窗口协议(连续ARQ协议)实现。
滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制

在建立连接时,接收方在报头中会携带接收窗口大小的信息。发送方的发送窗口不能超过接收方的接收窗口的数值。需要注意的是,TCP的窗口单位是字节而不是报文段。

流量控制引发的死锁
当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。

持续计时器
为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

3.3.4 拥塞控制

拥塞控制 和 流量控制 的区别?

  1. 拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况
  2. 流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收。流量控制往往指点对点通信量的控制,是个端到端的问题

拥塞控制的目的?

  1. 缓解网络压力
  2. 保证分组按时到达

慢开始算法 和 拥塞避免算法

  • 发送方维护一个发送窗口,发送窗口的大小取决于网络的拥塞情况和接收窗口的大小,发送窗口是动态变化的
  • 发送方还维护一个慢开始门限
    拥塞窗口 < 慢开始门限:使用慢开始算法
    拥塞窗口 > 慢开始门限:使用拥塞避免算法
    拥塞窗口 = 慢开始门限:使用慢开始算法或拥塞避免算法
  • 算法的具体过程:
    1.通信开始时,发送方的发送窗口设为1,并发送第一个分组M1;
    2.接收方收到M1后,返回确认应答,此时发送方发送窗口扩大两倍,并发送M2、M3;(即,发送方每次收到确认应答后,都将发送窗口设为当前值的两倍
    3.若拥塞窗口>慢开始门限,则使用拥塞避免算法,每次收到确认应答后都将发送窗口+1;
    4.若发送方出现了超时重传,则表明网络出现拥塞,此时:
    a)慢开始门限设为当前发送窗口的一半;
    b)发送窗口设为1;
    c)启用拥塞避免算法;

发送超时重传时,发送窗口有可能已经超过了慢开始门限,也有可能还没超过;此时不管何种情况,都一律启用拥塞避免算法,并执行上述三步操作!

  • 慢开始算法的作用:慢开始算法将发送窗口从小扩大,而且按指数级扩大,从而避免一开始就往网络中注入过多的分组从而导致拥塞;它将窗口慢慢扩大的过程其实也在探测网络拥塞情况的过程,当发现出现拥塞时,及时降低发送速度,从而减缓网络拥塞。慢开始算法不是增长很慢,只是初始值比较小
  • 拥塞避免算法的作用:拥塞避免算法使发送窗口以线性方式增长,而非指数级增长,从而使网络更加不容易发生拥塞
  • AIMD算法(加法增大乘法减小算法)
    慢开始算法 和 拥塞避免算法 还有个名称叫做加法增大乘法减小算法。
    加法增加:指的是拥塞避免算法,使得发送窗口以线性的方式增长;
    乘法减小:指的是不管当前正使用慢开始算法还是拥塞避免算法,只要发生拥塞时,慢开始门限将会变成当前窗口的一半。

快重传算法 和 快恢复算法

  • 上述慢开始算法和拥塞避免算法能保证网络出现拥塞时进行相应的处理,而快重传和快恢复是一种拥塞预防的方式,此时网络可能尚未出现拥塞,但已经有拥塞的征兆,因此得作出一些预防措施
  • 快重传原理:因为TCP具有累计确认的能力,因此接收者收到一个分组的时候不会立即发出应答,可能需要等待收到多个分组之后再同一发出累计确认。但快重传算法就要求,接收者如果接收到一个乱序的分组的话,就必须立即发出前一个正确分组的确认应答,这样能让发送者尽早地知道有一个分组可能丢失。
  • 快恢复原理:当发送者收到同一个分组的三个确认应答后,就基本可以判断这个分组已经丢失了;这时候无需等待超时,直接执行乘法减小加法增大(AIMD,将慢开始门限降为当前拥塞窗口的一半,然后直接采用拥塞避免算法,从慢开始门限开始)
    1.将慢开始门限减半;
    2.将发送窗口减半(不设为1);
    3.使用拥塞避免算法;
    在这里插入图片描述

总结
我们从上面的阐述可以发现,慢开始门限值是一个动态值,并且为出现超时时,把慢开始门限值设置为当前门限值的一半。此篇博客的内容主要来源依据是谢希仁编著的第六版《计算机网络》教材,在教材中没有见到慢开始门限的初始值的设置,查阅博客:tcp协议栈优化1-增加TCP初始拥塞窗口 ===》流氓的方式 后发现初始拥塞窗口为10,同时,TCP rcvwnd初始接收窗口也已调为10,此处拿出来仅供参考,实际值与使用的网络设置有关。在讨论原理的时候,部分地方可能将TCP传输的基本单位按照报文来进行讲解,其实TCP的传输基本单位是字节,这个在教材中也有说明。

并且在上面我们提到的一直是拥塞窗口,而部分博客为了方便理解把拥塞窗口直接改为了发送窗口,其实发送窗口≤拥塞窗口,绝大部分时候相等。

在TCP建立连接后,在整个传输过程中,发送窗口都小于等于接收窗口,这个在流量控制中有说明。现在假设接收窗口足够大,在发生网络拥塞的情况下还没有达到接收窗口的情况。在连接建立时,根据网络设置来初始化慢开始门限,初始建立连接时,使用慢开始算法,首先发送一个MSS分组,然后发送2个MSS分组,然后是4个,成指数倍增长。假设到达慢开始门限之前未发生网络拥塞,则会以指数倍增长方式加大到慢开始门限值。在达到慢开始门限值以后,采用拥塞避免算法,以线性增长的方式增大拥塞窗口,有的地方在讲解理论时说是增大一个MSS,也有地方说是增大0.1MSS,这对我们理解TCP传输没有影响。当发生网络拥塞后,慢开始门限值会做乘法减小,变为发送拥塞时的拥塞门限的一半,而不是前一个慢开始门限值的一半,刷新慢开始门限值,在TCP
Reno版本中,在发生网络拥塞之后,采用快重传和快恢复算法,在接收到三个相同的确认后就重传对方尚未确认的报文段,并且采用快速恢复算法而不是重新从慢开始算法开始来发送报文。

4 TCP报文段首部

此部分内容参考了博客:TCP三次握手和四次挥手过程
在这里插入图片描述
要理解TCP三次握手和四次挥手的过程,首先需要了解TCP报文段的某些首部的含义:

  • 序号 seq:本报文段所发送的数据的第一个字节序号
  • 确认号 ack:期望收到对方下一个报文段的第一个数据字节的序号
  • 确认位 ACK:仅当ACK=1时确认号字段才有效
  • 同步位 SYN:在连接建立时用来同步序号,SYN=1表示这是一个连接请求或是连接接受请求。
  • 终止位 FIN:用来释放一个连接。当FIN=1时,表示此报文段的发送方数据已经发送完毕,并要求释放运输连接

5 TCP三次握手和四次挥手过程

此部分引用了博客:TCP三次握手和四次挥手过程

5.1 TCP三次握手过程

在这里插入图片描述
(1)客户端A向服务端B发出连接请求,同步位SYN=1,初始序列seq=x,连接请求报文段不能携带数据,但是要消耗一个序号,这时客户端A进入SYN-SENT(同步已发送状态)。
(2)服务端B收到请求报文段之后,向A发送后确认。将同部位SYN和确认位都置为1,确认序号ack=x+1,同时自己选择一个初始序号seq=y。连接接收报文也不能携带数据,但是也要消耗一个序号,这时服务端进入SYN-RCVD(同步收到状态)。
(3)A收到B的确认时候要给B一个确认。确认报文段的确认位ACK=1,确认号ack=y+1,自己的序号seq=x+1。这时,TCP连接已经建立,客户端进入ESTABLISHED(已建立连接状态)。B收到A发出的确认报文之后也进入已建立连接状态。

5.2 三次握手常见问题

(1)为什么客户端还需要再发送一次确认?
主要是为了防止已经失效的连接请求报文段突然又传到了B,因而产生错误。“已失效的连接请求报文段”的产生在这样一种情况下:A发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了(因为网络并发量很大在某结点被阻塞了),以致延误到连接释放以后的某个时间才到达B。但是B收到此失效的报文段后,就认为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。如果不采用三次握手,那么只要B发出确认,新的连接就建立了,B的许多资源就白白浪费。
(2)SYN Flood攻击
SYN Flood攻击指利用tcp协议缺陷发送大量伪造的TCP连接请求,从而使被攻击方资源耗尽(CPU满负载或者内存不足)的攻击法方式。解决方法:

  • 缩短 SYN Timeout 时间缩短从接收到 SYN 报文到确定这个报文无效并丢弃该连接的时间,但是过低的SYN Timeout可能会影响用户正常访问。
  • 设置 SYN Cookie给每一个请求连接的 IP 地址分配一个 Cookie,如果短时间内连续受到某个IP的重复 SYN 报文,就认定是受到了攻击,以后从这个 IP 地址来的包会被丢弃
  • 使用硬件防火墙

5.3 TCP四次挥手过程

在这里插入图片描述
(1)客户端进程发出连接释放报文,并且停止发送数据。A将连接释放报文的终止位FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1)。此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
(2)服务器收到连接释放报文后发出确认,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向的连接就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
(3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)
(4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认
(5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,客户端才进入CLOSED状态
(6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。

5.3.4 四次挥手常见问题

(1) 为什么A在WAIT-TIME状态必须等待2MSL的时间?

  • 为了保证A发送的最后一个确认报文段能够达到B。这个ACK报文段可能丢失,因而使处在LAST-ACK状态的B收不到A发送的FIN+ACK报文段的确认。B会超时重传这个ACK+FIN报文段,而A就能在这个时间内收到这个重传的报文。接着A在再重传一次确认报文,并且重启2MSL计时器。使A和B都能正常的进入释放连接状态。
  • 防止已经关闭的连接报文段出现在新的连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有旧报文段都从网络中消失。这样新的连接中不会出现旧连接的数据报文。

(2) 为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是由于服务端的LISTEN状态下收到SYN报文的建立连接请求后。它能够把ACK和SYN(ACK起应答作用。而SYN起同步作用)放在一个报文里来发送给客户端。
但关闭连接的时候,当服务端收到客户端的FIN报文段的时候,表示客户端没有数据发送给服务端了,但是服务端可能还有数据要发送给客户端,这时TCP连接处于半连接状态。当服务端没有数据再发送给客户端的时候就会向客户端发送一个FIN报文表示服务端要关闭连接,ACK和FIN一般不会分开发送。这个过程也是由于TCP的通信方式是全双工的,发送和接收方都需要发送FIN和ACK。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值