• 计算机网络原理 运输层


    一,运输层协议概述

    1,进程之间的通信

    • 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最底层。当网络边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时,都要使用协议栈中的运输层,而网络核心部分中的路由器在转发分组时只用到下三层的功能。
    • 为什么需要运输层?
      • 从IP层来说,通信的两端是两台主机。IP数据报的首部明确地标志了这两台主机的IP地址。但“两台主机之间的通信”这种说法还不够明确。真正进行通信的实体是在主机中的哪个构件呢?是主机中的应用进程,一台主机中的应用进程和另一台主机中的应用进程在交换数据(即通信)。因此严格的讲,两台主机进行通信就是两台主机中的应用进程互相通信。IP协议虽然能把分组送到目的主机,但是这个分组还停留在主机的网络层而没有交付主机中的应用进程。通信的两端应当是两个主机中的应用进程。就是说,端到端的通信是应用进程之间的通信。
      • 运输层还有一个很重要的功能—复用multiplexing)和分用demultiplexing)。“复用”是指在发送方不同的应用进程都可以使用同一个运输层协议传送数据(当然要加上适当的首部),而“分用”是指接收方的运输层在剥去报文的首部后能够把这些数据正确交付目的应用进程。
      • 运输层提供应用进程间的逻辑通信”。“逻辑通信”的意思是:从应用层看,只要把应用层报文交给下面的运输层,运输层就可以把这报文传送到对方的运输层,好像这种通信就是沿水平方向直接传送数据。但事实上这两个运输层之间并没有一条水平方向的物理连接。
      • 网络层为主机之间的通信提供服务,而运输层则在网络层的基础上,为应用进程之间的通信提供服务。
      • 运输层还要对收到的报文进行差错控制。在网络层,IP数据报首部中的检验和字段,只检验首部是否出现差错而不检查数据部分。
    • 根据应用程序的不同需求,运输层有两种不同的运输协议,即面向连接的TCP无连接的UDP
    • 运输层向高层用户屏蔽了下面网络核心的细节它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的(只提供尽最大努力服务),但这种逻辑通信信道就相当于一条全双工的可靠信道。但当运输层采用无连接的UDP协议时,这种逻辑通信信道仍然是一条不可靠信道

    2,运输层的两个主要协议

    • TCP/IP运输层的两个主要协议都是互联网的正式标准,即:

      • 用户数据报协议UDP(User Datagram Protocol)
      • 传输控制协议TCP(Transmission Control Protocol)
    • 两种协议在协议栈中的位置。

      • 在这里插入图片描述
    • 按照OSI的术语,两个对等运输实体在通信时传送的数据单位叫作运输协议数据单元TPDUTransport Protocol Data Unit)。但在TCP/IP体系中,则根据所使用的协议是TCPUDP,分别称为TCP报文段segment)或UDP用户数据报

    • UDP在传送数据之前不需要先建立连接。远地主机的运输层在收到UDP报文后,不需要给出任何确认。虽然UDP不提供可靠交付,但由于UDP非常简单,在某些情况下UDP是一种最有效的工作方式。

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

    • 常用的应用和应用层协议主要使用的运输层协议

      • 应用应用层协议运输层协议
        名字转换DNS(域名系统)UDP
        文件传送TFTP(简单文件传送协议)UDP
        路由选择协议RIP(路由信息协议)UDP
        IP地址配置DHCP(动态主机配置协议)UDP
        网络管理SNMP(简单网络管理协议)UDP
        远程文件服务器NFS(网络文件系统)UDP
        IP电话专用协议UDP
        流式多媒体通信专用协议UDP
        多播IGMP(网际组管理协议)UDP
        电子邮件SMTP(简单邮件传送协议)TCP
        远程终端接入TELNET(远程终端协议)TCP
        万维网HTTP(超文本传送协议)TCP
        文件传送FTP(文件传送协议)TCP

    3,运输层的端口

    • 当应用层要发送数据时,应用进程就把数据发送到适当的端口,然后运输层从该端口读取数据,进行后续的处理(把数据发送到目的主机)。当运输层收到对方主机发来的数据时,就把数据发送到适当的端口,然后应用进程就从该端口读取这些数据。显然,端口必须有一定容量的缓存来暂时存放数据。
    • TCP/IP的运输层用一个16位的端口号来标志一个端口。注意,端口号只具有本地意义,它只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。在互联网不同计算机中,相同的端口号是没有关联的。16位的端口号可允许有65535个不同的端口号,对一台计算机来说是足够的。
    • 两个计算机中的进程要互相通信,不仅必须要知道对方的IP地址(为了找到对方的计算机),而且要知道对方的端口号(为了找到对方计算机中的应用进程)。
    • 互联网上的计算机通信是采用客户—服务器方式。客户在发起通信请求时,必须先知道对方服务器的IP地址(用来找到目的主机)和端口号(用来找到目的进程)。因此运输层的端口号又可分为两大类。
      • 服务器端使用的端口号:又可分为两类,最重要的一类叫作熟知端口号wellknown port number)或全球通用端口号,数值为01023**。常用的熟知端口号如下,另一类叫作**登记端口号**,数值为**102449151。这类端口号是为没有熟知端口号的应用程序使用的。

      • 在这里插入图片描述

      • 客户端使用的端口号

        • 数值为49152~65535。这类端口号仅在客户进程运行时才动态选择,因此又叫作短暂端口号
        • 这类端口号就是临时端口号,留给客户进程选择临时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的端口号,因此可以把数据发送给客户进程。通信结束后,刚才已使用过的客户端口号就被系统收回,以便给其他客户进程使用。

    二,用户数据报协议UDP

    1,UDP概述

    • 用户数据报协议UDP只在IP的数据报服务之上增加了很少一点的功能,就是复用分用以及差错检测的功能。UDP的主要特点是:
      1. UDP是无连接的。即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
      2. UDP使用尽最大努力交付。即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
      3. UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。就是说,UDP一次交付一个完整的报文。因此,应用程序必须选择合适大小的报文。若报文太长,UDP把它交给IP层后,IP层在传送时可能要进行分片,这会降低IP层的效率。反之,若报文太短,UDP把它交给IP层后,会使IP数据报的首部的相对长度太大,也会降低IP层的效率。
      4. UDP没有拥塞机制。因此网络出现的拥塞不会使源主机的发送速率降低。
      5. UDP支持一对一,一对多,多对一和多对多的交互通信
      6. UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。

    2,UDP的首部格式

    • 用户数据报UDP有两个字段:数据字段首部字段首部字段只有8个字节,由4个字段组成,每个字段的长度都是2字节。各字段意义如下:
      • 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。
      • 目的端口:目的端口号。这在终点交付报文时必须使用。
      • 长度UDP用户数据报的长度,其最小值是8(仅有首部)。
      • 检验和:检测UDP用户数据报在传输时是否有错。有错就丢弃。

    在这里插入图片描述

    • 如果接收方UDP发现收到的报文中的目的端口号不正确,就丢弃该报文,并由网际控制报文协议IGMP发送“端口不可达”差错报文给发送方。
    • UDP用户数据报首部中检验和的计算方法有些特殊。在计算检验和时,要在UDP用户数据报之前增加12个字节的伪首部。所谓“伪首部”是因为这种伪首部并不是UDP用户数据报真正的首部。只是在计算检验和时,临时添加在UDP用户数据报前面的,得到一个临时的UDP用户数据报。检验和就是按照这个临时的UDP用户数据报来计算的。伪首部既不向下传送也不向上递交,而仅仅是为了计算检验和
    • UDP计算检验和的方法和计算IP数据报首部检验和的方法相似。不同的是:IP数据报的检验和只检验IP数据报的首部,但UDP的检验和是把首部和数据部分一起都检验。

    三,传输控制协议TCP

    1,TCP最主要的特点

    • TCP是面向连接的运输层协议。应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。
    • 每一条TCP连接只能有两个端点endpoint),每一条TCP连接只能是点对点的(一对一)。
    • TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错,不丢失,不重复,并且按序到达。
    • TCP提供全双工通信TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。
    • 面向字节流。“”(stream)指的是流入到进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不一),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。TCP并不知道所传送的字节流的含义。TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。

    2,TCP的连接

    • TCP把连接作为最基本的抽象TCP的许多特征都与TCP是面向连接的这个基本特征有关。
    • 每一条TCP连接有两个端点TCP连接的端点叫作套接字socket)或插口。根据RFC 793的定义:端口号拼接到concatenated withIP地址即构成了套接字。因此,套接字的表示方法是在点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开:套接字 socket = (IP地址:端口号)。每一条TCP连接唯一地被通信两端的两个端点(即套接字对socket pair)所确定。即:TCP连接 ::= { s o c k e t 1 socket_1 socket1 s o c k e t 2 socket_2 socket2} = {( I P 1 IP_1 IP1 p o r t 1 port_1 port1),( I P 2 IP_2 IP2 p o r t 2 port_2 port2)}
    • TCP连接的端点是个很抽象的套接字,即(IP地址:端口号)。也还应该记住:同一个IP地址可以有多个不同的TCP连接,而同一个端口号也可以出现在多个不同的TCP连接中。
    • 注意,随着网络的发展,同一个名词socket却可以表示成多种不同的意思,例如:
      • socket API中使用的一个函数名也叫作socket
      • 调用socket函数的端点称为socket,如“创建一个数据报socket”。
      • 调用socket函数时,其返回值称为socket描述符,简称为socket
      • 在操作系统内核中连网协议的Berkeley实现,称为socket实现
      • 允许应用程序访问连网协议的应用编程接口APIApplication Programming Interface),即运输层和应用层之间的一种接口,称为socket API,简称为socket

    四,可靠传输的工作原理

    • TCP发送的报文段是交给IP层传送的。但IP层只能提供尽最大努力服务,就是说,TCP下面的网络所提供的服务是不可靠的传输。因此,TCP必须采用适当的措施才能使得两个运输层之间得通信变得可靠。理想的传输条件有以下两个特点
      1. 传输信道不产生差错
      2. 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
    • 然而实际的网络都不具备以上两个理想条件。但我们可以使用一些可靠传输协议,当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速率。

    1,停止等待协议

    • 全双工通信的双方既是发送方也是接收方。下面为了方便仅考虑A发送数据而B接收数据并发送确认。因此A叫作发送方,而B叫作接收方。因为此处讨论可靠传输的原理,因此把传送的数据单元都称为分组,而并不考虑数据是在哪个层次上传送的(运输层传送的协议数据单元叫作报文段,网络层传送的协议数据单元叫作IP数据报。但一般讨论问题时,都可以把它们简称为分组)。“停止等待”就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。

    1,无差错情况

    • 无差错情况可用下图表示。A发送分组 M 1 M_1 M1,发完就暂停发送,等待B的确认。B收到了 M 1 M_1 M1就向A发送确认。A在收到了对 M 1 M_1 M1的确认后,就再发送下一个分组 M 2 M_2 M2。同样,在收到B对 M 2 M_2 M2的确认后,再发送 M 3 M_3 M3

      在这里插入图片描述

    2,出现差错

    • 出现差错情况可用下图表示。B接收 M 1 M_1 M1时检测出了差错,就丢弃 M 1 M_1 M1,其他什么也不做(不通知A收到有差错的分组)。也可能是 M 1 M_1 M1在传输过程中丢失了,这时B当然什么都不知道。在这两种情况下,B都不会发送任何信息。可靠传输协议是这样设计的:A只要超过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组。这就叫作超时重传。要实现超时重传,就要在每发送完一个分组时设置一个超时计时器。如果在超时计时器到期之前收到了对方的确认,就撤销已设置的超时计时器。

    • 出现差错应注意3个问题:

      1. A在发送完一个分组后,必须暂时保留已发送的分组的副本(在发生超时重传时使用)。只有在收到相应的确认后才能清除暂时保留的分组副本。
      2. 分组和确认分组都必须进行编号。这样才能明确是哪一个发送出去的分组收到了确认,而哪一个分组还没有收到确认。
      3. 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。

      在这里插入图片描述

    3,确认丢失和确认迟到

    1,确认丢失
    • B所发送的对 M 1 M_1 M1的确认丢失了。A在设定的超时重传时间内没有收到确认,并无法知道是自己发送的分组出错,丢失,或者是B发送的确认丢失了。因此A在超时计时器到期后就要重传 M 1 M_1 M1。现在注意B的动作。假定B又收到了重传的分组 M 1 M_1 M1。这时应采取两个行动。
      1. 丢弃这个重复的分组 M 1 M_1 M1,不向上层重复交付。
      2. 向A发送确认。不能认为已经发送过确认就不再发送,因为A之所以重传 M 1 M_1 M1就表示A没有收到对 M 1 M_1 M1的确认。

    在这里插入图片描述

    2,确认迟到
    • 传输过程没有出现差错,但B对分组 M 1 M_1 M1的确认迟到了。A会收到重复的确认。对重复的确认的处理很简单:收下后就丢弃,但什么也不做。B仍然会收到重复的 M 1 M_1 M1,并且同样要丢弃重复的 M 1 M_1 M1,并重传确认分组。
    • 通常A最终总是可以收到对所有发出的分组的确认。如果A不断重传分组但总是收不到确认,就说明通信线路太差,不能进行通信。

    在这里插入图片描述

    4,信道利用率

    • 停止等待协议的优点是简单,但缺点是信道利用率太低。
    • 为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据在不间断地传送。这种传输方式可以获得很高的信道利用率。常用的流水线传输协议有连续ARQ协议滑动窗口协议

    2,连续ARQ协议

    • 下图a表示发送方维持的发送窗口,它的意义是:位于发送窗口内的5个分组都可连续发送出去,而不需要等待对方的确认。这样,信道利用率就提高了。
    • 连续ARQ协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。图b表示了发送方收到了对第一个分组的确认,于是把发送窗口向前移动一个分组的位置。如果原来已经发送了前5个分组,那么现在就可以发送窗口内的第6个分组了。
    • 接收方一般都是采用累计确认的方式。就是说,接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认
    • 累计确认的优点是容易实现,即使确认丢失也不必重传;缺点是不能向发送方及时反映接收方已经正确收到所有分组的信息。

    在这里插入图片描述

    五,TCP报文段的首部格式

    • TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段。一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在它首部中各字段的作用。

    在这里插入图片描述

    • TCP报文段首部的前20个字节是固定的,后面有 4 n 4n 4n字节是根据需要而增加的选项( n n n是整数)。因此TCP首部的最小长度是20字节。
      1. 源端口目的端口:各占2个字节,分别写入源端口号和目的端口号。
      2. 序号:占4字节。序号范围是[0, 2 32 − 1 2^{32}-1 2321],共 2 32 2^{32} 232个序号。序号增加到 2 32 − 1 2^{32}-1 2321后,下一个序号就又回到0。
      3. 确认号:占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。
      4. 数据偏移:占4位,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。这个字段实际上是指出TCP报文段的首部长度。由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。
      5. 保留:占6位,保留为今后使用,目前应置为0
      6. 紧急URGURGent):当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),而不要按原来的排队顺序传送。当URG置1时,发送应用进程就告诉发送方的TCP有紧急数据要传送。于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍是普通数据。这时要与首部中紧急指针Urgent Pointer)字段配合使用。
      7. 确认ACKACKnowledgment):仅当ACK=1时确认号才有效。当ACK=0时,确认号无效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1
      8. 推送PSHPuSH):当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP就可以使用推送(push)的操作。此时,发送方TCPPSH1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
      9. 复位RSTReSeT):当RST=1时,表明TCP连接中出现了严重差错(如主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。将RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。RST也称为重建位或重置位。
      10. 同步SYNSYNchronization):在连接建立时用来同步序号。当SYN=1ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1ACK=1。因此,SYN置为1就表示这是一个连接请求或连接接收报文。
      11. 终止FINFINish,意思是“完了”):用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
      12. 窗口:占2字节。窗口值是[0, 2 16 − 1 2^{16}-1 2161]之间的整数。窗口指的是发送本报文段的一方的接收窗口(而不是自己的窗口)。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。
      13. 检验和:占2字节。检验和字段检验的范围包括首部和数据两部分。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式与UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6),把第5字段中的UDP长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用IPv6,则相应的伪首部也要改变。
      14. 紧急指针:占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。
      15. 选项:长度可变,最长可达40字节。当没有使用“选项”时,TCP的首部长度是20字节。最后的填充字段仅仅是为了使整个TCP首部长度是4字节的整数倍TCP最初只规定了一种选项,即最大报文段长度MSSMaximum Segment Size)。MSS是每一个TCP报文段中的数据字段的最大长度。数据字段加上TCP首部才等于整个的TCP报文段。所有MSS并不是整个TCP报文段的最大长度,而是“TCP报文段长度减去TCP首部长度”。

    六,TCP可靠传输的实现

    1,超时重传时间的选择

    • TCP的发送方在规定的时间内没有收到确认就要重传已发送的报文段。但是重传时间的选择却是TCP最复杂的问题之一。
    • 由于TCP的下层是互联网环境,发送的报文段可能只经过一个高速率的局域网,也可能经过多个低速率的网络,并且每个IP数据报所选择的路由还可能不同。如果把超时重传时间设置的太短,就会引起许多报文段的不必要的重传,使网络负荷增大。但若把超时重传时间设置得过长,则又使网络得空闲时间增大,降低了传输效率。那么,运输层得超时计时器的超时重传时间究竟应设置为多大呢?
    • TCP采用了一种自适应算法,记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间RTTTCP保留了RTT的一个加权平均往返时间 R T T s RTT_s RTTs(这又称为平滑的往返时间,S表示Smoothed。因为进行的是加权平均,因此得出的结果更加平滑)。每当第一次测量到RTT样本时, R T T s RTT_s RTTs值就取为所测量到的RTT样本值。但以后每测量到一个新的RTT样本,就按照如下公式重新计算一次 R T T s RTT_s RTTs
      • 新的 R T T s RTT_s RTTs = (1-α)x(旧的 R T T s RTT_s RTTs)+ α x(新的RTT样本)
    • 上面式子中,0 ≤ α<1,若α很接近于零,表示新的 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值更新较快)。
    • 超时计时器设置的超时重传时间RTORetransmission Time-Out)应略大于上面得出的加权平均往返时间 R T T s RTT_s RTTsRFC 6298建议使用下面公式计算RTO
      • RTO = R T T s RTT_s RTTs + 4 x R T T D RTT_D RTTD
    • R T T D RTT_D RTTDRTT的偏差的加权平均值,它与 R T T S RTT_S RTTS和新的RTT样本之差有关。RFC 6298建议这样计算 R T T D RTT_D RTTD。当第一次测量时, R T T D RTT_D RTTD值取为测量到的RTT样本值的一半。在以后的测量中,使用下式计算加权平均的 R T T D RTT_D RTTD:
      • 新的 R T T D RTT_D RTTD = (1- β \beta β)x(旧的 R T T D RTT_D RTTD)+ β \beta β x | R T T S RTT_S RTTS-新的RTT样本|
      • 这里 β \beta β是个小于1的系数,它的推荐值是1/4。

    2,选择确认SACK

    • 如果收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?选择确认Selective ACK)就是一种可行的处理方法。
    • 如下图,TCP的接收方在接收对方发送过来的数据字节流的序号不连续,结果就形成了一些不连续的字节块。可以看出,序号1—1000收到了,但序号1001—1500没有收到。接下来的字节流又收到了,可是缺少了3001—3500。再后面从序号4501起又没有收到。就是说,接收方收到了和前面的字节流不连续的两个字节块。如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。

    在这里插入图片描述

    • 上图中前后字节不连续的每一个字节块都有两个边界:左边界右边界,图中用四个指针标记这些边界。注意,第一个字节块的左边界 L 1 L_1 L1=1501,但右边界 R 1 R_1 R1=3001而不是3000。就是说,左边界指出字节块的第一个字节的序号,但右边界减1才是字节块的最后一个序号
    • TCP的首部没有哪个字段能够提供上述这些字节块的边界信息。RFC 2018规定,**如果要使用选择确认SACK,那么在建立TCP连接时,就要在TCP首部的选项中加上“允许SACK”的选项,而双方必须都事先商定好。如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。只是以后在TCP报文段的首部中都增加了SACK选项,以便报告收到的不连续的字节块的边界。由于首部选项的长度最多只有40字节,而指明一个边界就要用掉4字节(因为序号有32位,需要使用4个字节表示),因此在选项中最多只能指明4个字节块的边界信息。这是因为4个字节块共有8个边界,因而需要用32个字节来描述。另外还需要两个字节,一个字节用来指明是SACK选项,另一个字节指明这个选项要占用多少字节。**如果要报告5个字节块的边界信息,那么至少需要42个字节。这就超过了选项长度40字节的上限。
    • SACK文档并没有指明发送方应当怎样响应SACK。因此大多数的实现还是重传所有未被确认的数据块

    七,TCP的流量控制

    1,利用滑动窗口实现流量控制

    • 我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快,接收方就可能来不及接收,就会造成数据的丢失。所谓流量控制flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收

    • 利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。

      在这里插入图片描述

    • 上图中设A向B发送数据。在连接建立时,B告诉A:“我的接收窗口rwnd=400”(rwnd,receiver window)。因此,发送方的发送窗口不能超过接收方给出的接收窗口的数值。注意,TCP的窗口单位是字节,不是报文段。TCP连接建立时的窗口协商过程在图中没有显示。再设一个报文段为100字节长,而数据报文序号的初始值设为1(图中第一个箭头上面的序号seq=1)。图中箭头上面大写ACK表示首部中的确认位ACK,小写ack表示确认字段的值。

    • 注意,接收方的主机B进行了三次流量控制。第一次把窗口减小到rwnd=300,第二次又减小到rwnd=100,最后减到rwnd=0,即不允许发送方再发送数据了。这种使发送方暂停发送的状态将持续到主机B重新发出一个新的窗口值为止。注意,B向A发送的三个报文段都设置了ACK=1,只有在ACK=1时确认好字段才有意义。

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

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

    八,TCP的拥塞控制

    1,拥塞控制的一般原理

    • 在计算机网络中的链路容量(即带宽),交换节点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫作拥塞congestion)。
    • 所谓拥塞控制就是防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不至于过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。但TCP连接的端点只要迟迟不能收到对方的确认信息,就猜想在当前网络中的某处很可能发生了拥塞,但这时却无法知道拥塞到底发生在网络的何处,也无法知道发生拥塞的具体原因。
    • 进行拥塞控制需要付出代价。这首先需要获得网络内部流量分布的信息。在实施拥塞控制时,还需要在节点之间交换信息和各种命令,以便选择控制的策略和实施控制。这样就产生了额外开销。拥塞控制有时需要将一些资源(如缓存,带宽等)分配给个别用户(或一些类别的用户)单独使用,这样就使得网络资源不能更好地实现共享。
    • 随着提供的负载的增大,网络吞吐量的增长速率逐渐减小。也就是说,在网络吞吐量还未达到饱和时,就已经有一部分输入分组被丢弃了。当网络的吞吐量明显地小于理想的吞吐量时,网络就进入了轻度拥塞的状态。当提供的负载达到某一数值时,网络的吞吐量反而随提供的负载的增大而下降,这时网络就进入了拥塞状态。当提供的负载继续增大到某一数值时,网络的吞吐量就下降到零,网络已无法工作,这就是所谓的死锁deadlock)。
    • 拥塞控制是很难设计的,因为它是一个动态的问题。当网络正朝着高速化的方向发展,这很容易出现缓存不够大而导致分组的丢失。但分组的丢失是网络发生拥塞的征兆而不是原因。在许多情况下,甚至正是拥塞控制机制本身成为引起网络性能恶化甚至发生死锁的原因。
    • 由于计算机网络是一个很复杂的系统,因此可以从控制理论的角度来看拥塞控制这个问题。这样,从大的方面看,可分为开环控制闭环控制两种方法。
      • 开环控制就是在设计网络时事先将发生拥塞的有关因素考虑周到,力求网络在工作时不产生拥塞。但一旦整个网络运行起来,就不再中途进行改正了。
      • 闭环控制是基于反馈环路的概念,主要有以下几种措施:
        1. 监测网络系统以便检测到拥塞在何时,何处发生。
        2. 把拥塞发生的信息传送到可采取行动的地方。
        3. 调整网络系统的运行以解决出现的问题。

    2,TCP的拥塞控制方法

    • TCP进行拥塞控制的算法有四种,即慢开始slow-start),拥塞避免congestion avoidance),快重传fast retransmit)和快恢复fast recovery)。

    1,慢开始

    • 基于窗口的拥塞控制。为此,发送方维持了一个叫作拥塞窗口cwndcongestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且是动态变化的。发送方让自己的发送窗口等于拥塞窗口。根据假定,对方的接收窗口足够大,发送方在发送数据时,只需考虑发送方的拥塞窗口。
    • 发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。
    • 发送方又如何知道网络发生了拥塞呢?当网络发生拥塞时,路由器就要把来不及处理而排不上队的分组丢弃。因此只要发送方没有按时收到对方的确认报文,也就是说,只要出现了超时,就可以估计可能在网络某处出现了拥塞。因此,发送方在超时重传计时器启动时,就判断网络出现了拥塞。
    • 慢开始的算法:当主机在已建立的TCP连接上开始发送数据时,并不清楚网络当前的负荷情况。如果立即把大量数据字节注入到网络,那么就有可能引起网络发生拥塞。经验证明,较好的方法是先探测一下,即由小到大逐渐增大注入到网络中的数据字节,就是说,由小到大逐渐增大拥塞窗口数值。RFC 5681标准定义:
      • 把初始拥塞窗口cwnd设置为不超过2至4个SMSS的数值。具体的规定如下:若SMSS > 2190字节,则设置初始拥塞窗口cwnd=2*SMSS字节,且不得超过2个报文段。若(SMSS > 1095字节)且(SMSS ≤ 2190字节),则设置初始拥塞窗口cwnd = 3 x SMSS字节,且不得超过3个报文段。若SMSS≤1095字节,则设置初始拥塞窗口cwnd = 4 x SMSS字节,且不得超过4个报文段。
    • 在一开始发送方先设置cwnd = 1,发送第一个报文段,接收方收到后就发送确认。慢开始算法规定,发送方每收到一个对新报文段的确认(对重传的确认不算在内),就把发送方的拥塞窗口加1。因此,经过一个往返时延RTT后,发送方就增大拥塞窗口,使cwnd = 2,即发送方现在可连续发送两个报文段。接收方收到这两个报文段后,先后发回两个确认。现在发送方收到两个确认,根据慢开始算法,拥塞窗口就应当加2,使拥塞窗口从cwnd = 2增加到cwnd = 4,即可连续发送4个报文段。发送方收到这4个确认后,就可以把拥塞窗口再加到4,使cwnd = 8。

    在这里插入图片描述

    • 为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(可以把门限ssthresh的数值设置大些,如达到发送窗口的最大容许值)。慢开始门限ssthresh的用法如下:
      • cwnd < ssthresh时,使用上述的慢开始算法。
      • cwnd > ssthresh时,停止使用慢开始算法而改用拥塞避免算法。
      • cwnd = ssthresh时,即可使用慢开始算法,也可使用拥塞避免算法。

    2,拥塞避免

    • 拥塞避免算法的目的是让拥塞窗口cwnd缓慢地增大。执行算法后的结果大约是这样的:每经过一个往返时间RTT,发送方的拥塞窗口cwnd的大小就加1,而不是像慢开始阶段那样成倍增加。因此在拥塞避免阶段就称为“加法增大AIAdditive Increase),表明在拥塞避免阶段,拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。

    3,快重传

    • 快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
    • 快重传算法规定,发送方只要一连收到3个重复确认,就可知道现在并未出现网络拥塞,而只是接收方少收到一个报文段,因此立即进行重传此报文段。使用快重传可以使整个网络的吞吐量提高约20%。

    3,主动队列管理AQM

    • TCP拥塞控制和网络层采取的策略有着密切联系。
    • 网络层的策略对TCP拥塞控制影响最大的就是路由器的分组丢弃策略。在最简单的情况下,路由器的队列通常都按照“先进先出FIFOFirst In First Out)的规则处理到来的分组。由于队列长度总是有限的,因此当队列已满时,以后再到达的所有分组将都被丢弃。这叫作尾部丢弃策略tail-drop policy)。
    • 路由器的尾部丢弃往往会导致一连串分组的丢失,这就使发送方出现超时重传,使TCP进入拥塞控制的慢开始阶段,结果使TCP连接的发送方突然把数据的发送速率降低到很小的数值。更严重的是,在网络层中通常有很多的TCP连接,这些连接中的报文段通常是复用在网络层的IP数据报中传送的。在这种情况下,若发生了路由器中的尾部丢弃,就可能会同时影响到很多条TCP连接,结果使这许多TCP连接在同一时间突然都进入到慢开始状态。这在TCP的术语中称为全局同步global synchronization)。全局同步使得全网的通信量突然下降了很多,而在网络恢复正常后,其通信量又突然增大很多。
    • 为了解决网络中的全局同步现象,1998年提出了主动队列管理AQMActive Queue Management)。“主动”指应当在队列长度达到某个值得警惕的数值时(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。这样就提醒了发送方放慢发送的速率,因而有可能使网络拥塞的程度减轻,甚至不出现网络拥塞。
    • AQM可以有不同的实现,其中曾流行多年的就是随机早期检测REDRandom Early Detection)。(2015年公布的RFC 7567已不再推荐使用RED)。
    • 实现RED时需要使路由器维持两个参数,即队列长度最小门限最大门限。当每一个分组到达时,RED就按照规定的算法先计算当前的平均队列长度。
      1. 若平均队列长度小于最小门限,则把新到达的分组放入队列进行排队。
      2. 若平均队列长度超过最大门限,则把新到达的分组丢弃。
      3. 若平均队列长度在最小门限和最大门限之间,则按照某一丢弃概率p把新到达的分组丢弃(这就体现了丢弃分组的随机性)。

    九,TCP的运输连接管理

    • TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中不可缺少的过程。运输连接就有三个阶段,即:连接建立数据传送连接释放
    • TCP连接建立过程要解决以下三个问题。
      1. 要使每一方能够确知对方的存在。
      2. 要允许双方协商一些参数。
      3. 能够对运输实体资源进行分配。
    • TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫作客户client),被动等待连接建立的应用进程叫作服务器server)。

    1,TCP的连接建立

    • TCP建立连接的过程叫作握手,握手需要在客户和服务器之间交换三个TCP报文段。称为三报文握手
    • 假定主机A运行的是TCP客户程序,而B运行TCP服务器程序。最初两端的TCP进程都处于CLOSED关闭)状态。在本例中,A主动打开连接,而B被动打开连接。
    • 开始,B的TCP服务器进程先创建传输控制块TCB,准备接收客户进程的连接请求。然后服务器进程就处于LISTEN收听)状态,等待客户的连接请求。

    在这里插入图片描述

    • 三报文握手如下
      1. A的TCP客户进程首先创建传输控制块TCB。然后,在打算建立TCP连接时,向B发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段(即SYN=1的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态。
      2. B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN位和ACK位都置1,确认号是ack=x+1,同时也要自己选择一个初始序号seq=y。注意,这个报文段也不能携带数据,但同时要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
      3. TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1TCP标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq=x+1。这时,TCP连接已经建立,A进入ESTABLISHED状态。当B收到A的确认后,也进入ESTABLISHED状态。

    2,TCP的连接释放

    • 数据传输结束后,通信的双方都可以释放连接。

    在这里插入图片描述

    • 四报文握手如下
      1. A和B都处于ESTABLISHED状态。A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序号seq=u,它等于前面已传送过的数据的最后一个字节的序号加1。这时A进入FIN-WAIT-1终止等待1)状态,等待B的确认。注意,TCP规定,FIN报文段即使不携带数据,它也消耗掉一个序号
      2. B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1。然后B就进入CLOSE-WAIT关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭half-close)状态,即A已经没有数据要发送了。但B若发送数据,A仍要接收。就是说,从B到A这个方向的连接并未关闭,这个状态可能还要持续一段时间。A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
      3. 若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1。现假定B的序号为w(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack=u+1。这时B就进入LAST-ACK最后确认)状态,等待A的确认。
      4. A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)。然后进入到TIME-WAIT时间等待)状态。注意,现在TCP连接还没有释放掉。必须经过时间等待计时器TIME-WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态。时间MSL叫作最长报文段寿命Maximim Segment Lifetime)。RFC 793建议设为2分钟。
  • 相关阅读:
    2022年高教社杯国赛E题思路——小批量物料的生产安排
    Unity 2021 LTS / Unity 2022 LTS New Shader Graph Node 参考样本
    自动驾驶仿真:VTD调用罗技 G923方向盘(Linux环境)
    MIKE水动力笔记20_由dfs2网格文件提取dfs1断面序列文件
    C语言框架FreeSwitch自定义事件介绍与使用示例
    swin_transformer源码详解
    【Linux】Centos 8 服务器部署:阿里云域名注册、域名解析、个人网站 ICP 备案详细教程
    Android Settings 单元测试 | Telephony Network 模块 APN 案例
    第五十三周总结——云文档开发一周总结
    线性回归的神经网络法——机器学习
  • 原文地址:https://blog.csdn.net/JAVAYmm/article/details/132783574