计算机网络导航🚀🚀🚀

  1. 🍕第一章 概述

  2. 🍔第二章 物理层

  3. 🍟第三章 数据链路层

  4. 🌭第四章 网际层

  5. 🍿第五章 运输层 ⇦ 当前位置🪂

  6. 🧂第六章 应用层

图片加载较慢,请耐心等待!🌤️🌥️🌦️

运输层概述

  • 之前课程所介绍的计算机网络体系结构中的物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的问题,实现了 主机到主机的通信
  • 但实际上在计算机网络中进行通信的真正实体是位于 通信两端主机中的进程
  • 如何为运行在不同主机上的应用进程提供直接的通信服务是运输层的任务,运输层协议又称为端到端协议
  • 运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用进程看见的就好像是在两个运输层实体之间有一条端到端的逻辑通信信道
  • 根据应用需求的不同,因特网的运输层为应用层提供了两种不同的运输协议,即 面向连接的TCP无连接的UDP,这两种协议就是本章要讨论的主要内容

知识点一:运输层端口号、复用与分用的概念

  • 运行在计算机上的进程使用 进程标识符PID 来标志:
  • 因特网上的计算机并不是使用统一的操作系统,不同的操作系统(windows,Linux,MacOS)又使用不同格式的进程标识符
  • 为了使运行不同操作系统的计算机的应用进程之间能够进行网络通信,就必须使用统一的方法对TCP/IP体系的应用进程进行标识
  • TCP/IP体系的运输层使用 端口号 来区分应用层的不同应用进程
  • 端口号使用16比特表示,取值范围 0~65535
    • 熟知端口号 0 ~1023,IANA把这些端口号指派给了TCP/IP体系中最重要的一些应用协议,例如:FTP使用21/20,HTTP使用80,DNS使用53
    • 登记端口号 1024~49151,为没有熟知端口号的应用程序使用。使用这类端口号必须在IANA按照规定的手续登记,以防止重复。例如:Microsoft RDP微软远程桌面使用的端口是3389
    • 短暂端口号 49152~65535,留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用
  • 端口号只具有本地意义,即端口号只是为了标识本计算机应用层中的各进程,在因特网中不同计算机中的相同端口号是没有联系的

TCP/IP体系的应用层常用协议所使用的运输层熟知端口号

Untitled

运输层传输流程

举例

  1. 在浏览器输入域名,回车浏览
  2. 然后用户PC中的DNS客户端进程会发送一个DNS查询请求报文
    • DNS查询请求报文需要使用运输层的UDP协议
    • 首部中的源端口字段的值,在短暂端口号49151~65535中挑选一个未被占用的,用来表示DNS客户端进程
    • 首部中的目的端口字段的值:53,是DNS服务器端进程所使用的熟知端口号
  3. 之后,用户PC将UDP用户数据报封装在IP数据报中,通过以太网发送给DNS服务器
  4. DNS服务器收到该IP数据报后,从中解封出UDP用户数据报
    • UDP首部中的目的端口号为53,这表明应将该UDP用户数据报的数据载荷部分,也就是DNS查询请求报文,交付给本服务器中的DNS服务器端进程
    • DNS服务器端进程解析DNS查询请求报文的内容,然后按其要求查找对应的IP地址
    • 之后,会给用户PC发送DNS响应报文,DNS响应报文需要使用运输层的UDP协议封装成UDP用户数据报
    • 其首部中的源端口字段的值设置为熟知端口号53,表明这是DNS服务器端进程所发送的UDP用户数据报,目的端口的值设置为49152,这是之前用户PC中发送DNS查询请求报文的DNS客户端进程所使用的短暂端口号
  5. DNS服务器将UDP用户数据报封装在IP数据报中,通过以太网发送给用户PC
  6. 用户PC收到该数据报后,从中解封出UDP用户数据报
    • UDP首部中的目的端口号为49152,这表明应将该UDP用户数据报的数据载荷部分,也就是DNS响应报文,交付给用户PC中的DNS客户端进程
    • DNS客户端进程解析DNS响应报文的内容,就可知道自己之前所请求的Web服务器的域名对应的IP地址
  7. 现在用户PC中的HTTP客户端进程可以向Web服务器发送HTTP请求报文(和DNS发送和接收流程差不多)

✨知识点二:UDP和TCP的对比

UDP TCP
无连接 面向连接
支持一对一,一对多,多对一和多对多交互通信 每一条TCP连接只能有两个端点EP,只能是一对一通信
对应用层交付的报文直接打包 面向字节流
尽最大努力交付,也就是不可靠;不使用流量控制和拥塞控制 可靠传输,使用流量控制和拥塞控制
首部开销小,仅8字节 首部最小20字节,最大60字节

两个对等运输实体在通信时传送的数据单位叫作 运输协议数据单元 TPDU (Transport Protocol Data Unit)。

  • TCP 传送的数据单位协议是 TCP 报文段(segment)。
  • UDP 传送的数据单位协议是 UDP 报文或用户数据报
  • UDP的通信是无连接的,不需要套接字(Socket)
  • TCP是面向连接的,TCP之间的通信必须要在两个套接字(Socket)之间建立连接

TCP报文段运输过程

发送方

  • TCP会把应用进程交付下来的数据块看作是一连串无结构的字节流,TCP并不知道这些待传送的字节流的含义
  • 并将他们编号,并存储在自己发送缓存中
  • TCP会根据发送策略,提取一定量的字节构建TCP报文并发送

接收方

  • 一方面从所接受到的TCP报文段中,取出数据载荷部分并存储在接收缓存中;一方面将接收缓存中的一些字节交付给应用进程
  • TCP不保证接收方应用进程所收到的数据块与发送方发送的数据块,具有对应大小的关系(例如,发送方应用进程交给发送方的TCP共10个数据块,但接收方的TCP可能只用了4个数据块,就把收到的字节流交付给了上层的应用进程,但接收方收到的字节流必须和发送方应用进程发出的字节流完全一样)
  • 接收方的应用进程必须有能力识别收到的字节流,把它还原成有意义的应用层数据

✨知识点三:TCP的流量控制

引入

一般来说,我们总是希望数据传输得更快一些。

但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失

所谓流量控制(flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收

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

TCP接收方利用自己的接收窗口的大小来限制发送方发送窗口的大小

TCP发送方收到接收方的零窗口通知后,应启动持续计时器。持续计时器超时后,向接收方发送零窗口探测报文

举例

Untitled

Untitled

如果零窗口探测报文在发送过程中如果丢失,还是能打破死锁局面

因为 零窗口探测报文段也有重传计时器,重传计时器超时后,零窗口探测报文段会被重传

Untitled


✨知识点四:TCP的拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏。这种情况就叫做 拥塞 (congestion)

在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源

出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降

网络拥塞往往是由许多因素引起的

例如:

  1. 点缓存的容量太小
  2. 链路的容量不足
  3. 处理机处理的速率太慢
  4. 拥塞本身会进一步加剧拥塞

监测网络的拥塞

主要指标有:

  1. 由于缺少缓存空间而被丢弃的分组的百分数
  2. 平均队列长度
  3. 超时重传的分组数
  4. 平均分组时延
  5. 分组时延的标准差,等等

上述这些指标的上升都标志着拥塞的增长

拥塞控制的算法

发送方维护一个叫做拥塞窗口cwnd的状态变量,其值取决于网络的拥塞程度,并且动态变化

  • 拥塞窗口cwnd的维护原则:只要网络没有出现拥塞,拥塞窗口就再增大一些;但只要网络出现拥塞,拥塞窗口就减少一些
  • 判断出现网络拥塞的依据:没有按时收到应当到达的确认报文(即发生超时重传)

发送方将拥塞窗口作为发送窗口swnd,即swnd=cwnd

维护一个慢开始门限ssthresh状态变量(防止拥塞窗口增长过大引起网络拥塞)

  • 当cwnd<ssthresh时,使用慢开始算法
  • 当cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法
  • 当cwnd =ssthresh时,既可使用慢开始算法,也可使用拥塞避免算法

🌐 真正的发送窗口值 = Min (接收方窗口值,拥塞窗口值)

传输轮次:

  1. 发送方给接收方发送数据报文段后,接收方给发送方发发回相应的确认报文段
  2. 一个传输轮次所经历的时间其实就是往返时间,往返时间并非是恒定的数值
  3. 使用传输轮次是为了强调把拥塞窗口所允许发送的报文段都连续发送出去,并受到了对已发送的最后一个报文段的确认

Untitled

慢开始(slow-start)

每经过一个传输轮次,拥塞窗口就加倍

拥塞避免(congestion avoidance)

每经过一个传输轮次,拥塞窗口 cwnd =
cwnd + 1

快重传(fast retrasmit)

  • 要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认
  • 即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认
  • 发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等该报文段的超时重传计时器超时再重传

快恢复(fast recovery)

发送方一旦收到3个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而执行快恢复算法

发送方将慢开始门限ssthresh值和拥塞窗口cwnd值调整为当前窗口的一半

开始执行拥塞避免算法

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

重传计时器超时

判断网络很可能出现了拥塞,进行以下工作

  1. 将ssthresh值更新为发生拥塞时cwnd值的一半
  2. cwnd值减少为1,并重新开始执行慢开始算法

✨知识点五:TCP超时重传时间的选择

如果超时重传时间RTO的值设置得比往返时间RTT0的值小很多,这会引起报文段不必要的重传,使网络负荷增大

如果超时重传时间RTO的值设置得远大于往返时间RTT0的值,这会使重传时间推迟的太长,使网络的空闲时间增大,降低传输效率

RFC6298建议使用下式计算超时重传时间RTO

Untitled

针对出现超时重传时无法测准往返时间RTT的问题,Karn提出了一个算法:在计算加权平均往返时间RTTS时,只要报文段重传了,就不采用其往返时间RTT样本。也就是出现重传时,不重新计算RTTS,进而超时重传时间RTO也不会重新计算

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

因此,要对Karn算法进行修正。方法是:报文段每重传一次,就把超时重传时间RTO增大一些。典型的做法是将新RTO的值取为I日RTO值的2倍

Untitled


✨知识点六:TCP可靠传输的实现

TCP基于 以字节为单位的滑动窗口 来实现可靠传输

  • TCP基于以字节发送方在未收到接收方的确认时,可将发送窗口内还未发送的数据全部发送出去
  • 接收方只接收序号落入发送窗口内的数据
  • 后沿的移动情况有两种情况
    • 不动(没有收到新的确认)
    • 前移(收到了新的确认)
  • 前沿的移动情况有三种可能:
    • 通常是不断向前移动
    • 不动
      • 没有收到新的确认,对方通知的窗口大小也不变
      • 收到新确认但对方通知的窗口缩小,使发送窗口前沿正好不动;
    • 向后收缩(对方通知的窗口缩小了)

如何描述发送窗口的状态?

Untitled

虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的发送窗口并不总是和接收方的接收窗口一样大

  • 网络传送窗口值需要经历一定的时间滞后,并且这个时间还是不确定的
  • 发送方还可能根据网络当时的拥塞情况适当减小自己的发送窗口尺寸

对于不按序到达的数据应如何处理,TCP并无明确规定

  • 如果接收方把不按序到达的数据一律丢弃,那么接收窗口的管理将会比较简单,但这样做对网络资源的利用不利,因为发送方会重复传送较多的数据
  • TCP通常对不按序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程

TCP要求接收方必须有 累积确认和捎带确认机制,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。

  • 接收方不应过分推迟发送确认,否则会导致发送方不必要的超时重传,这反而浪费了网络的资源
  • TCP标准规定,确认推迟的时间不应超过0.5秒。若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认[RFC 1122]
  • 捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据

TCP的通信是全双工通信。通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和接收窗口。在谈到这些窗口时,一定要弄清楚是哪一方的窗口。

Untitled

Untitled


✨知识点七:TCP的运输连接管理

  • TCP是面向连接的协议,它基于运输连接来传送TCP报文段。
  • TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。
  • TCP运输连接有以下 三个阶段
    1. 建立TCP连接
    2. 数据传送
    3. 释放TCP连接
  • TCP的运输链接管理就是使运输连接的建立和释放都能正常地进行

🌐 TCP的连接建立

TCP 建立连接的过程叫做握手

握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手

采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误

TCP的连接建立要解决以下三个问题

  • 使TCP双方能够确知对方的存在
  • 使TCP双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)
  • 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配

建立连接过程

TCP 连接的建立采用 客户服务器方式

主动发起连接建立的应用进程叫做 TCP客户 (client)

被动等待连接建立的应用进程叫做 TCP服务器 (server)

  1. 最初两端的TCP进程都处于关闭状态(CLOSED)
  2. 一开始,TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息。例如TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针,当前的发送和接收序号等

    之后,就准备接受TCP客户端进程的连接请求

    此时,TCP服务器进程就进入监听状态(LISTEN),等待TCP客户端进程的连接请求(TCP服务器进程是被动等待来自TCP客户端进程的连接请求,因此成为被动打开连接)

  3. TCP客户进程也是首先创建传输控制块(由于TCP连接建立是由TCP客户端主动发起的,因此称为主动打开连接)

  4. 然后,在打算建立TCP连接时,向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态(SYN-SENT)
  • TCP连接请求报文段首部中

    • 同步位SYN被设置为1,表明这是一个TCP连接请求报文段
    • 序号字段seq被设置了一个初始值x,作为TCP客户端进程所选择的初始序号
    • 请注意:TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号
  1. TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态(SYN-RCVD)
  • TCP连接请求确认报文段首部中

    • 同步位SYN和确认为ACK都设置为1,表明这是一个TCP连接请求确认报文段
    • 序号字段seq被设置了一个初始值y,作为TCP服务器进程所选择的初始序号,
    • 确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号(seq)的确认
    • 请注意:这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号
  1. TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态(ESTABLISHED)
  • 普通的TCP确认报文段首部中

    • 确认位ACK被设置为1,表明这是一个普通的TCP确认报文段
    • 序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,所以TCP客户进程发送的第二个报文段的序号为x+1
    • 确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认
    • 请注意:TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号
  1. TCP服务器进程收到该确认报文段后也进入连接已建立状态(ESTABLISHED)
  2. 现在,TCP双方都进入了连接已建立状态,它们可以基于已建立好的TCP连接,进行可靠的数据传输

Untitled

Untitled

🌐 TCP的连接释放

  • TCP 连接释放过程比较复杂。
  • 数据传输结束后,通信的双方都可释放连接(任何一方都可以在数据传送结束后发出连接释放的通知)
  • TCP 连接释放过程是四报文握手
  1. 现在TCP客户进程和TCP服务器进程都处于连接已建立状态
  2. TCP客户进程的应用进程通知其主动关闭TCP连接
  3. TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态
  • TCP连接释放报文段首部中
    • 终止位FIN和确认为ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认
    • 序号seq字段的值设置为u,它等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1
    • 确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1
    • 请注意:TCP规定终止位FIN等于1的报文段即使不携带数据,也要消耗掉一个序号
  1. TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态
  • 普通的TCP确认报文段首部中
    • 确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段
    • 序号seq字段的值设置为v,它等于TCP服务器进程之前已传送过的数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配
    • 确认号ack字段的值设置为u+1,这是对TCP连接释放报文段的确认
  1. TCP服务器进程应该通知高层应用进程,TCP客户进程要断开与自己的TCP连接
  • 此时,从TCP客户进程到TCP服务器进程这个方向的连接就释放了
  • 这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了
  • 但如果TCP服务器进程还有数据要发送,TCP客户进程仍要接收,也就是说从TCP服务器进程到TCP客户进程这个方向的连接并未关闭
  1. TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段
  • 若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程就通知其TCP服务器进程释放连接
  • 由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接
  1. TCP服务器进程发送TCP连接释放报文段并进入最后确认状态

    该报文段首部中

  • 终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认
  • 序号seq字段的值为w,这是因为在半关闭状态下,TCP服务器进程可能又发送
  • 确认号ack字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认
  1. TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态
  • 该报文段首部中
    • 确认为ACK的值被设置为1,表明这是一个普通的TCP确认报文段
    • 序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号
    • 确认号ack字段的值设置为w+1,这是对所收到的TCP连接释放报文段的确认
  1. TCP服务器进程收到该报文段后就进入关闭状态,而TCP客户进程还要进过2MSL后才能进入关闭状态

Untitled

TCP客户进程在发送完最后一个确认报文后,为什么不直接进入关闭状态?而是要进入时间等待状态

  1. 因为时间等待状态以及处于该状态2MSL时长,可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态
  2. 另外,TCP客户进程在发送完最后一个TCP确认报文段后,在经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中,不会出现旧连接中的报文段

TCP保活计时器的作用

TCP双方已经建立了连接,后来,TCP客户进程所在的主机突然出现了故障

TCP服务器进程以后就不能再收到TCP客户进程发来的数据

因此,应当有措施使TCP服务器进程不要再白白等待下去

措施:

TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)

若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发送10个探测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接


✨知识点八:TCP报文段的首部格式

Untitled

Untitled