传输层

传输层功能

从通信和信息处理的角度看,传输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。
传说层位于网络层之上,为运行在不同主机上的进程之间提供了逻辑通信。而网络层只提供主机之间的逻辑通信。显然,即使网络层协议不可靠(网络层协议使分组丢失、混乱或重复),传输层同样能为应用程序提供可靠的服务。
网络层的边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时,只有主机的协议栈才有传输层和应用层,而路由器在转发分组时都只用到下三层(物理层、数据链路层、网络层)的功能。
传输层的功能如下:

  • 传输层提供应用进程之间的逻辑通信(即端到端的通信)。

与网络层的区别是,网络层提供的是主机之间的逻辑通信。从网络层来说,通信的双方是两台主机,IP数据报的首部给出了这两台主机的IP地址,但“两台主机之间的通信”实际上是主机中应用进程之间的通信,应用进程之间的通信又称端到端的逻辑通信。

  • 复用和分用。

复用是指发送方不同的应用进程都可使用同一个传输层协议传送数据。
分用是指接收方的传输层在剥去报文首部后能够把这些数据正确交付到目的应用进程。
网络层也有复用分用的功能,但网络层的复用是指发送方不同协议的数据都可以封装成IP数据包发送出去,分用是指接收方的网络层在剥去首部后把数据交付给相应的协议。

  • 传输层还要对收到的报文进行差错检测(首部和数据部分)。而网络层只检验IP数据报的首部,不检验数据部分是否出错。
  • 提供两种不同的传输协议,即面向连接的TCP协议和无连接的UDP协议。而网络层无法同时实现两种协议(要么只提供面向连接的服务,如虚电路;要么只提供无连接服务,如数据报。而不可能在网络层同时提供这两种服务)。


传输层向高层用户屏蔽了低层网络核心的细节(如网络拓扑、路由协议),使应用进程看见的只是两个传输层实体之间好像有一条端到端的逻辑通信信道。这条逻辑通信信道对最上层的表现与传输层协议有很大关系,当传输层采用面向连接的TCP时,尽管下面的网络是不可靠的,但这种逻辑通信信道就相当于一条全双工的可靠信道。

传输层的寻址与端口

端口能够让应用层的各种应用进程将数据向下交付给传输层,以及让传输层数据段向上通过端口交付给应用层的相应进程。
端口是传输层服务访问点(TSAP),它在传输层的作用类似于IP地址在网络层的作用,只不过IP地址和MAC地址标识的是主机,而端口标识的是主机中的应用进程(数据链路层的SAP是MAC地址,网络层的SAP是IP地址)。
在协议栈层间的抽象的协议端口是_软件端口_。它与路由器或交换机上的硬件端口是完全不同的概念。硬件端口是不同硬件设备进行交互的接口,而软件端口是应用层各种协议进程与传输层实体进行层间交互的一种地址。传输层使用的是软件接口。
应用程序通过端口号进行标识,端口号长度为16bit,能够表示65536(216)个不同的端口号。端口号只具有本地意义,只标识本计算机应用层内的各进程。
根据端口号范围,可将端口分为两类:

  • 服务器使用的端口号。它又分为两类,最重要的一类是熟知端口号,数值为01023,互联网地址指派机构IANA把这些端口号指派给了TCP/IP最重要的一些应用程序。另一类称为登记端口号,数值为102449151。供没有熟知端口号的应用程序使用,要使用这类端口号必须在IANA登记,以防止重复。

  • 客户端使用的端口号。数值为49152~65535。由于这类端口号仅在应用进程运行时才动态地选择,因此又称为短暂端口号,也称临时端口。通信结束后,刚用过的客户端口号就不复存在,所以客户端口号可以重复使用。

在网络中通过IP地址来标识或区别不同的主机,通过端口号来表示和区别一台主机中不同应用进程,端口号拼接到IP地址即构成套接字Socket。在网络中采用发送方和接收方的套接字来识别端点。
套接字实际上是一个通信断点。套接字Socket = (IP地址:端口号)
套接字唯一的标识网络中的一台主机上面的一个应用进程。在网络通信中,主机A发给主机B的报文段中包含目的端口号和源端口号,源端口号是返回地址的一部分(完全返回地址是A的IP地址+源端口号)。

无连接服务和面向连接服务

面向连接服务就是通信双方在进行通信之前必须先建立连接,在通信过程中,整个连接的情况一直被实时地监控和管理,通信结束后需要释放连接。
无连接服务是指两个实体之间的通信不需要先建立好连接,需要通信时直接将信息发送到网络中,让该信息的传递在网络上尽力地往目的地传送。
TCP/IP协议在传输层使用了两个传输协议:
一个是面向连接的传输控制协议TCP。
采用TCP时,传输层向上提供的是一条全双工的可靠逻辑信道。

  • TCP提供面向连接的服务,在传输数据之前必须先建立连接,传输结束后要释放连接。
  • TCP不提供广播服务或组播服务。
  • 由于TCP提供面向连接的可靠传输服务,因此不可避免的增加了许多开销,如确认、流量控制、计时器和连接管理等,不仅使协议数据单元的首部增大很多,还需要占用许多处理机资源。

TCP主要适合于可靠性更重要的场合,如文件传输协议(FTP),超文本传输协议(HTTP)、远程登录(TELNET)。
另一个是无连接的用户数据报协议UDP。
采用UDP时,传输层向上提供的是一条不可靠的逻辑信道。
UDP在IP之上仅提供两个附加服务:多路复用和数据的差错校验。

  • UDP在传输数据之前不需要先建立连接,接收方传输层收到UDP报文后不需要给出任何确认

由于UDP比较简单,因此执行速度快,实时性好,使用UDP的应用主要包括小文件传送协议(TFTP)、DNS、SNMP和实时传输协议(RTP)。

IP数据报和UDP数据报的区别:

  • IP数据报在网络层需要经过路由的存储转发;而UDP数据报在传输层的端到端的逻辑信道中传输,封装成IP数据报在网络层传输时,UDP数据报的信息对路由器是不可见的。

TCP和网络层虚电路的区别:

  • TCP报文段在传输层抽象的逻辑信道中传输,对路由器不可见;虚电路所经过的交换结点都必须保存虚电路状态信息。
  • 在网络层若采用虚电路方式,则在传输层无法提供无连接服务,而在传输层采用TCP不影响网络层提供无连接服务。

UDP协议

UDP仅在IP的数据报服务之上增加了两个最基本的服务:分用和复用以及差错检测。
UDP的优点:

  • UDP无需建立连接,因此UDP不会引入建立连接的时延。

试想如果DNS运行在TCP而非UDP上,那么DNS的速度就会慢很多。HTTP使用TCP而非UDP是因为对于基于文本数据的web网页来说,可靠性是至关重要的。

  • 无连接状态。TCP需要在端系统中维护连接状态。连接状态包括接收和发送缓存、拥塞控制参数、序号与确认号参数。而UDP不维护连接状态,也不跟踪这些参数。因此某些专业应用服务器在使用UDP时,一般都能支持更多的客户机。
  • 分组首部开销小。TCP的首部有20B,而UDP只有8B的开销。
  • 应用层能够更好地控制要发送的数据和发送时间。

UDP没有拥塞控制,因此网络中的拥塞不会影响主机的发送效率。某些实时应用要求以稳定的速度发送,能容忍一些数据的丢失,UDP正好满足这些应用的需求。

  • UDP支持一对一、一对多、多对一和多对多的交互通信。

UDP常用于一次性传输较少的数据的网络应用,如DNS,SNMP等,因为对于这些应用,若采用TCP,则将因为连接创建、维护和拆除导致不小的开销。UDP也常用于多媒体应用(如IP电话、实时视频会议、流媒体等),显然可靠数据传输对于这些应用来说并不是最重要的。
UDP不保证可靠交付,但这并不意味着应用对数据的要求是不可靠的,所有维护可靠性的工作在应用层完成,应用开发者可根据应用的需求来灵活设计自己的可靠性机制。
UDP是面向报文的。发送方UDP对应用层交下来的报文,在添加首部后就向下交付给IP层,一次发送一个报文,既不合并也不拆分,而是保留这些报文的边界;接收方UDP对IP层交上来的UDP数据报,在去除首部后就原封不动地交给上层应用进程,一次交付一个完整的报文,因此UDP报文不可分割,是UDP协议处理最小单位。因此,应用程序必须选择合适大小的报文,若报文太长,UDP把它交给IP层后可能会导致分片,若报文太短,UDP把它交给IP层后会使IP数据报的首部的相对长度太大,两者都会降低IP层的效率。

UDP的首部格式

UDP数据报分为两部分:UDP首部和用户数据。

UDP首部有8B,由四个字段组成,每个字段的长度都是2B。各字段意义如下:

  • 源端口。源端口号,在需要对方回信时选用,不需要时可置为全0。
  • 目的端口。目的端口号,在终点交付报文时必须用的。
  • 长度。UDP数据报的长度(包含首部和数据),其最小值为8(仅有首部)。
  • 校验和。检测UDP数据报在传输中是否有错,有错就丢弃。该字段是可选的。当源主机不想计算校验和时,将该字段置为全0。

当时传输层从IP层收到UDP数据报时,就根据首部中的目的端口把UDP数据报通过相应的端口上交给应用进程。如果接收方UDP发现收到的报文中目的端口号不正确(即不存在相应端口号的应用进程),就丢弃报文,并由ICMP发送端口不可达差错报文给发送方。

UDP校验

在计算校验和时,要在UDP数据报之前增加12B的伪首部。伪首部只是在计算校验和时临时添加在UDP数据报前面得到一个临时的UDP数据报。
校验和就是按照这个临时的UDP数据报来计算的。伪首部既不向下传送,也不向上递交。UDP校验和的计算方法和IP数据报首部校验和的计算方法类似。但不同的是,IP数据报的校验和只校验IP数据报的首部,而UDP的校验和校验首部和数据部分。
这种简单的差错校验方法的检测能力并不强,但好处是简单,处理速度快。

发送方发送UDP数据报时:

  1. 发送方首先把全0放入校验和字段并添加伪首部,然后把UDP数据报视为许多16位的字,串连起来。
  2. 若UDP数据报的数据部分不是偶数个字节,则要在数据的部分的末尾填入一个全0字节,但此字节不发送。
  3. 按二进制反码计算出这些16位字的和,将此和的二进制反码写入校验和字段,并发送。

接收方收到UDP数据报后:

  1. 将收到的UDP数据报加上伪首部,若不为偶数个字节,那么还在数据部分末尾补上全0字节。
  2. 按二进制反码求这些16位的字的和,若无差错,其结果应全为1,否则就表明有差错出现,接收方就应该丢弃该UDP数据报。

如果校验出UDP数据报是错误的,那么就可以丢弃,也可以交付给上层,但是要附上错误报告,告诉上层这是错误的数据报。

通过伪首部不仅可以检查源端口号、目的端口号、数据部分,还可以检查IP数据包的源IP地址和目的地址。

TCP协议

TCP是在不可靠的IP层之上实现的可靠的数据传输协议,主要解决传输的可靠、有序、无丢失和不重复问题。
TCP的主要特点如下:

  • TCP是面向连接的传输层协议,TCP连接是一条逻辑连接。
  • 每条TCP连接只能有两个端点,每条TCP连接只能是端到端的(进程对进程)。
  • TCP提供可靠交付的服务,保证传输的数据无差错、不丢失、不重复且有序。
  • TCP提供全双工通信,允许通信双方的应用进程在任何时候都能发送数据。

为此,TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。
发送缓存用来暂存以下数据:发送应用程序传送给发送方TCP准备发送的数据、TCP已发送但尚未收到的确认的数据。
接收缓存用来暂存以下数据:按序到达但尚未被接收应用程序读取的数据、不按序到达的数据。

  • TCP是面向字节流的,虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅视为一连串的无结构字节流。

TCP和UDP在发送报文时所采用的方式完全不同。
UDP报文的长度由发送应用进程决定;TCP报文的长度则根据接收方给出的窗口值和当前网络的拥塞程度来决定。
如果应用进程传送到TCP缓存的数据块太长,TCP就把它划分的短一些再发送,如果太短,TCP也可以等积累到足够多的字节后再构成报文段发送出去。

TCP报文段

TCP传送的数据单元称为报文段。TCP报文段既可以用来运载数据,又可以用来建立连接、释放连接和应答。
一个TCP报文段分为首部和数据两部分,整个TCP报文段作为IP数据报的数据部分封装在IP数据报中。
TCP首部最短为20B,后面有根据需要而增加的选项,长度为4B的整数倍。

TCP的全部功能体现在其首部的各个字段中,各字段意义如下

  • 源端口和目的端口。各占2B。端口是运输层和应用层的服务接口,运输层的复用和分用功能都要通过端口实现。
  • 序号。占4B。范围为0~232-1,共232个序号。TCP是面向字节流的(即TCP传送时是逐个字节传送的)。所以TCP连接传送时的字节流中的每个字节都要按顺序编号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。例如,报文段的序号字段值是301,而携带的数据共有100B,表明本报文段的数据的最后一个字节的序号是400,因此下一个报文的数据序号应从401开始。
  • 确认号。占4B。是期望对收到对方下一个报文段的第一个数据字节的序号。若确认号为N,则表明序号N - 1之前的所有数据都已正确收到。例如,B正确收到了A发送过来的一个报文段,其序号字段是501,而数据长度是200B(序号501~700)。B正确收到了A发送的到序号700为止的数据,因此期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。
  • 数据偏移(即首部长度)。占4_位_。这里不是IP数据报分片的那个数据偏移,而是表示首部长度(首部中还有长度不确定的选项字段)。该字段指出TCP报文段中的数据的起始处距离TCP报文段起始处有多远。数据偏移的单位是32位(以4B为计算单位)。因此TCP首部的最大长度为60B。
  • 保留。占6位。保留为今后使用,但目前应置为0。
  • 紧急位URG。当URG = 1时。表明紧急指针字段有效。用于告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。但URG需要和首部中紧急指针字段配合使用(数据从第一个字节到紧急指针所指字节就是紧急数据)。
  • 确认位ACK。当ACK = 1时有效。TCP规定在连接建立后,所有传送的报文段都必须把ACK字段置为1。
  • 推送位PSH(Push)。接收方TCP收到等于PSH = 1的报文段,就尽快交付给接收应用进程,而不再等到整个缓存都填满之后再向上交付。
  • 复位位RST(Reset)。当RST = 1时,表明TCP连接中出现严重差错(如主机崩溃或其他原因),必须释放连接,然后重新建立运输连接。
  • 同步位SYN。当SYN = 1时表示这是一个连接请求或连接接受报文。当SYN = 1、ACK = 0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使用SYN = 1、ACK = 1。
  • 终止位FIN(Finish)。用来释放一个连接。当FIN = 1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
  • 窗口。占2B。范围为0216-1。指出现在允许对方发送的数据量。接收方的数据缓存空间是有限的,因此用窗口值作为让发送方设置其发送窗口的依据。例如,确认号为701。窗口字段是1000。这表明从701号算起,发送此报文段的一方还有接收1000字节(字节序号为7011700)数据的接收缓存空间。
  • 校验和。占2B。检验的范围包括首部和数据两部分。在计算校验和时,和UDP一样,要在TCP报文段的前面加上12B的伪首部(只需将UDP伪首部的第4个字段,即协议字段的17改为6,其他和UDP伪首部一样)。
  • 紧急指针。占2B。仅在URG = 1时才有意义。指出本报文段中紧急数据共有多少字节。紧急数据都在报文段数据的最前面。
  • 选项。长度可变。TCP最初只规定了一种选项,即最大报文段长度(MSS),用于指明TCP报文段中的数据段的最大长度。
  • 填充。使整个首部长度是4B的整数倍。

MSS应尽量大一些,只要在IP层传输时不要再分片就最好。然而最佳的MSS是很难确定的,由于IP数据报所经历的路径是动态变化的,在一条路径上确定的不需要分片的MSS,在另外一条路径上可能就需要分片。
MSS的默认值为536B,因此因特网上的所有主机能接收的TCP报文段长度为556B = 536B + 20B(首部)

TCP的连接管理

TCP是面向连接的协议,因此每个TCP连接都有三个阶段:连接建立、数据传送和连接释放。TCP连接的管理就是使运输连接的建立和释放都能正常进行。
在TCP建立的过程中,需要解决以下三个问题:

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

TCP把连接作为最基本的抽象对象,每条TCP连接有两个端点,TCP连接的端点不是主机,不是IP地址,不是应用进程,也不是传输层的协议端口,而是套接字Socket或插口。每个TCP连接唯一地被通信的两个端点(即两个套接字)确定。
TCP连接的建立采用客户端/服务器模式,主动发起连接建立的应用程序成为客户,而被动等待连接建立的应用进程称为服务器。

TCP连接的建立

TCP连接的建立分以下三个步骤,通称三次握手

连接建立前,服务器进程处于收听状态。等待客户的连接请求。

  1. 客户机的TCP首先向服务器的TCP发送连接请求报文段。这个特殊报文段的首部中的同步位SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。
  2. 服务器的TCP收到连接请求报文段后,若同意建立连接,则向客户机发回确认。并为该TCP连接分配缓存和变量。在确认报文段中,同步位SYN=1和确认位ACK=1,确认号ack=x+1,同时也为自己选择一个初始序号seq=y。注意确认报文段不能携带数据,但也要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
  3. 当客户机收到确认报文段后,还要向服务器给出确认,并为该TCP连接分配缓存和变量。确认报文段的确认位ACK=1,确认号ack=y+1,序号seq=x+1。该报文段可以携带数据若不携带数据则不消耗序号(seq=x)。这时TCP客户进程进入ESTABLISHED(已建立连接)状态。

注意:
服务端的资源是在完成第二次握手时分配的,而客户端资源是在完成第三次握手时分配的。这就使得服务器易收到SYN洪泛攻击。

为什么不采用“两次握手”建立连接?
两次握手情况下会出现下面情况:

  1. 客户端A向服务器B发送TCP连接请求报文①,但①滞留在网络中迟迟没有到达B,从而超时。
  2. 客户端A再向服务器B发送TCP连接请求报文②,顺利到达B,B发回确认(两次握手),连接建立。
  3. A与B传送完数据后,TCP连接释放。
  4. 此时①到达B,B发回确认,此时B进入连接建立状态,而A收到确认报文,不予理睬,B的资源白白浪费。

TCP连接的释放

参与TCP连接的任何一个进程都能终止该连接。TCP连接释放的过程通常称为四次握手

  1. 客户机打算关闭连接时,向其TCP发送连接释放报文段,并停止发送数据,主动关闭TCP连接。该报文段终止位FIN=1,序号seq=u,等于前面已经传送过的数据的最后一个字节的序号+1。FIN报文段即使不携带数据也消耗掉一个序号。这时TCP客户进程进入FIN-WAIT-1(终止等待1)状态。TCP是全双工的,即可以想象一条TCP连接上有两条数据通路,发送FIN的一端不能再发送数据,即关闭了其中一条数据通路,但对方还可以发送数据。
  2. 服务器收到连接释放报文段后即发出确认。确认号ack=u+1。序号seq=v,等于它前面已传送过的数据的最后一个字节的序号+1。然后服务器进入CLOSE-WAIT(关闭等待)状态。此时,从客户机到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接还未关闭。
  3. 若服务器已经没有要向客户机发送的数据,就通知TCP释放连接。发出连接释放报文段,其FIN=1,设该报文段的序号seq=w(在半关闭状态服务器可能又发送了一些数据),并且还要重复上次已发送的确认号ack=u+1。这时服务器进入LAST-ACK(最后确认)状态。
  4. 客户机收到连接释放报文段后必须发出确认。把确认报文段中的确认位ACK=1,确认号ack=w+1,序号seq=u+1。此时TCP还未释放,必须等待计时器设置的时间2MSL(最长报文段寿命)后,客户机才进入CLOSED(连接关闭)状态。

为什么不采用“三次握手”释放连接,且发送最后一次握手报文后,要等待2MSL的时间?

  1. 为了保证A发送的最后一个确认报文段能够到达B。如果A不等待2MSL,若A最后发送的确认报文段丢失,则B不能进入关闭状态,而此时A已经进入关闭状态,不可能再重传。
  2. 为了防止“已失效的连接请求报文段”。A在发送完最后一个确认报文段后,再经过2MSL可保证本连接持续的时间内所产生的所有报文段从网络中消失。保证了后续的连接不会出现旧连接的报文段。

对TCP连接的建立和释放的总结:
连接建立:

  1. SYN=1,seq=x
  2. SYN=1,ACK=1,seq=y,ack=x+1
  3. ACK=1,seq=x+1,ack=y+1

释放连接:

  1. FIN=1,seq=u
  2. ACK=1,seq=v,ack=u+1
  3. FIN=1,ACK=1,seq=w,ack=u+1
  4. ACK=1,seq=u+1,ack=w+1

TCP的可靠传输

TCP的任务是在IP层不可靠服务的基础上,建立一种可靠数据传输服务。
TCP提供的可靠数据传输服务,保证接收方进程从缓冲区读出的字节流与发送方发出的字节流完全一样。TCP使用了校验、序号、确认和重传等机制来达到这一目的。

校验

TCP的校验机制与UDP一样。

序号

TCP首部的序号字段用来保证数据能有序提交给应用层。TCP把数据视为一个无结构但有序的字节流,序号建立在传送的字节流之上,而不建立在报文段之上。TCP连接传送的数据流的每个字节都编上一个序号,序号字段的值是指本报文段发送的数据的第一个字节的序号。

确认

TCP首部的确认号是期望收到对方下一个报文段的数据的第一个字节的序号。在上图中,若B已收到第一个报文段,则B期望收到的下一个报文段是从序号3开始的,即B发送给A的报文中确认号ack=3。
发送方缓存区会继续存储那些已发送但未收到确认的报文段,以便在需要时重传。
TCP默认使用累计确认,即TCP只确认数据流中至第一个丢失字节为止的字节。例如B只都收到了包含序号02和67字节的报文段,但此时B仍在等待序号3开始的报文段,所以发送给A的报文中确认号还是ack=3。

重传

有两种事件会导致TCP对报文进行重传:超时和冗余ACK。

  • 超时

TCP每发送一个报文段,就对这个报文段设置一次计时器。计时器设置的重传时间到期但还未收到确认时,就要重传这一报文段。
由于TCP的下层是一个互联网环境,IP数据报所选择的路由变化很大,因而传输层的往返时延的方差也很大。为了计算超时计时器的重传时间,TCP采用一种自适应算法,它记录一个报文段发出的时间,以及收到确认的时间,这两个时间之差称为报文段的往返时间(RTT)。TCP保留了RTT的一个加权平均往返时间RTTs,它会随着新测量的RTT样本值变化而变化。显然,超时计时器设置的超时重传时间(RTO)应略大于RTTs,但也不能大太多,否则当报文段丢失时,TCP不能很快重传,导致数据传输时延过大。

在计算平均往返时延RTT时,只要重传了,就不采用其时间样本。且每重传一次,就把RTO增大一些。

  • 冗余ACK(冗余确认)

超时触发重传存在的一个问题是超时周期往往过长。所幸的是,发送方通常可在超时事件发生之前通过注意冗余ACK来较好地检测丢包情况。
冗余ACK就是再次收到某个报文段的ACK,而发送方先前已经收到过该报文段的确认。例如,A发送了序号为1,2,3,4,5的TCP报文段,其中2号报文段在链路中丢失。TCP规定每当比期望序号大的失序报文段到达时,就发送一个冗余ACK,指明下一个期待序号的报文段,在这里就是2号报文段。当接收方收到对同一个报文段的3个冗余ACK时,就认为该报文段已经丢失,立即重传。这种技术通常称为快速重传

TCP流量控制

TCP提供流量控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性,流量控制也可以说是一个速度匹配服务(匹配发送方的发送速率与接收方的读取速率)。
TCP提供的是基于滑动窗口协议的流量控制机制。
在通信中:

  • 接收方根据自己缓存区的大小,动态地调整发送方发送窗口的大小,称为_接收窗口rwnd_,即调整TCP报文段首部中的“窗口”字段值,来限制发送方的窗口大小。
  • 发送方根据其对网络拥塞程度的估计而确定的窗口值,称为_拥塞窗口cwnd_,其大小与网络的带宽和时延有关。

接受窗口rwnd表明接收方允许连续接收的最大能力,单位是字节。发送方总是根据最新收到的rwnd值来限制自己的发送窗口的大小,从而将未确认的数据量控制在rwnd大小范围内。
实际发送方的发送窗口大小取的是rwnd和cwnd中的最小值。

传输层和数据链路层的流量控制的区别是:

  • 传输层定义端到端用户之间的流量控制,数据链路层定义两个中间的相邻结点的流量控制
  • 传输层的窗口大小可以动态变化,数据链路层的窗口大小不能动态变化

TCP的基于滑动窗口的控制协议,是后退N帧(GBN)和选择重传(SR)的结合:

  • GBN的累积确认

当对报文序号k发送确认时,证明k以及前面的报文都已经正确接收了。

  • SR的选择确认

收到失序报文时,不会丢弃,而是缓存起来。对于丢失或出错的报文,只要求单独重传该报文。

TCP拥塞控制

拥塞控制是防止过多的数据注入网络,保证网络中的路由器或链路不至于过载。出现拥塞时,端点并不了解拥塞的细节,对通信连接的端点来说,拥塞往往表现为通信时延的增加。
拥塞控制和流量控制的区别:

  • 拥塞控制是让网络能够承受现有的网络负荷,是一个全局性的过程,涉及所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。拥塞控制中由发送方自己通过检测网络状况来控制发送速率。
  • 流量控制是点对点通信量的控制,是端到端的问题(接收端控制发送端),它所要做的是抑制发送端发送数据的速率,以便使接收端来得及接收。流量控制中由接收方控制发送方速率。

实际上发送方速率由拥塞控制和流量控制共同控制。

拥塞控制和流量控制的相似:

  • 都通过控制发送方速率来达到控制效果。

因特网标准定义了4种拥塞控制的算法:慢开始、拥塞避免、快重传和快恢复。
发送方在确定发送报文段的速率时,既要根据接收方的接受能力,又要从全局考虑不要使网络发生拥塞,因此发送方要同时维护两个窗口:

  • 接收窗口rwnd:反映接收方的接收能力
  • 拥塞窗口cwnd:反映网络的拥塞情况

发送方的发送窗口的上限值 = min[rwnd,cwnd]

慢开始

在TCP刚连接好时,先令拥塞窗口cwnd=1,即一个最大报文段长度MSS。每收到一个对新报文段的确认后,逐步增大发送方的cwnd,使分组注入网络的速率更加合理。
慢开始的慢不是指拥塞窗口增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,即只发送一个报文段试探一下网络的拥塞情况,之后在逐步增大cwnd,这对防止网络出现拥塞是一个很有力的措施。
使用慢开始算法后,每经过一个传输轮次(即往返时延RTT),cwnd就会加倍,即cwnd的值随传输轮次线性增长。一直把cwnd增大到一个规定的慢开始门限ssthresh(阈值),然后改用拥塞避免算法。

拥塞避免(发生了超时)

拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大。
每经过一个往返时延RTT就把发送方的拥塞窗口cwnd+1,而不是加倍,使得拥塞窗口cwnd按线性成长规律缓慢增长,这比慢增长算法的拥塞窗口增长速率缓慢得多。

根据cwnd大小:

  • 当cwnd < ssthresh时,使用慢开始算法
  • 当cwnd > ssthresh时,改用拥塞避免算法
  • 当cwnd = ssthresh时,通常使用拥塞避免算法,但也可以使用慢开始算法

无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断出现网络出现拥塞(未按时收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方的cwnd值的1/2(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。
这样做的目的是迅速减少主机发送到网络中的分组,使得发生拥塞的路由器有足够的时间把队列里积压的分组处理完。

在慢开始(指数级增长)阶段,若2cwnd > ssthresh,则下一个RTT后的cwnd = ssthresh,而不等于2cwnd,即cwnd不能跃过ssthresh值。

快重传

在TCP可靠传输机制中,快重传技术使用了冗余ACK来检测丢包的发生。同样,冗余ACK也用于网络拥塞的检测(丢包也是意味着网络可能出现了拥塞)。快重传并非代替重传计时器,而是在某些情况下可更早地重传丢失的报文段。
当发送方连续收到三个重复的ACK时,直接重传对方尚未收到的报文段,而不必等该报文段的计时器超时。

快恢复(收到了三个冗余的ACK)

是对慢开始和拥塞避免算法的改进。
当发送方连续收到三个冗余ACK时,执行“乘法减小”算法,把慢开始门限ssthresh设置为此时发送方cwnd的1/2。
但发送方现在认为网络很可能没有发送(严重)阻塞,否则就不会收到连续的几个冗余ACK。因此与慢开始算法不同的是,它把cwnd的值设置为慢开始门限ssthresh改变后的数值后,直接开始执行拥塞避免算法(加法增大),使拥塞窗口cwnd缓慢地线性增大。
由于跳过了拥塞窗口cwnd从1开始的慢开始过程,因此又称快恢复

总结

实际上,四种算法几乎同时出现在拥塞控制中:

  • 在TCP建立连接和网络出现超时时,采用慢开始和拥塞避免算法
  • 在发送方收到连续冗余ACK时,采用快重传和快恢复算法

发送方发送窗口的实际大小是由拥塞控制和流量控制共同决定的。

posted @ 2023-03-23 12:26  青子Aozaki  阅读(266)  评论(0)    收藏  举报