一、运输层协议概述
1、 进程之间的通信【复用和分用】
- 在了解进程之间的通信前,我们先来看看在五层协议的体系结构中各层的通信时如何定义的
- 可以看到,对于我们本文要总结的【运输层】,它可以向它上面的应用层提供通信服务,是属于面向通信部分的最高层,同时也是用户功能中的最低层。当网络边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时,都要使用协议栈中的运输层。
- 因此从上可以看出==运输层==在五层协议中也是至关重要的
接下去我们来说说复用和分用的概念📚
- 当两台主机进行通信时,真正进行通信的实体并不是两台主机本身,而是主机中的应用进程。因此严格来说:==通信双方进行端到端的通信时进行的是应用进程之间的通信==
- 那么对于多个进程之间的通信,就要涉及到我们的复用和分用的概念
- 【复用】:在发送方不同的应用进程都可以使用
同一个运输层协议
传送数据(当然需要加上适当的首部) - 【分用】:接收方的运输层之间有一个剥去报文的首部后能够把这些数据正确交付目的应用进程
然后我们来看看两个应用进程之间是如何通信的
- 不用说了,你可能会觉得比较难理解,对于这张图而言最主要的就是这两句话
👉网络层为主机之间的通信提供服务
👉传输层在网络层的基础上,为应用进程之间的通信提供服务
还有一个小知识点需要记忆📕
- 传输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。
2、 运输层的两个主要协议
==→敲黑板!!!重点来了←==
- 接下去,我们来说说运输层的两个主要协议,而且也是这一层中我们需要记住的唯一两个协议,而不会像网络层那样需要记忆那么多的协议,脑袋🧠都大了
1. TCP【传输控制协议】
- 提供可靠的、面向连接的运输服务(建立连接---》释放连接)
- 不提供广播或多播服务
- 开销较多(确认、流量控制、计时器以及连接管理)
2. UDP【用户数据包协议】
- 传送数据之前不需要建立连接
- 收到UDP报后,不需要给出任何确认
- 不提供可靠交付,但是确实一种最有效的工作方式
下面是有关TCP和UDP的应用层协议,以及各自的端口。可以适当了解一下
3、 运输层的端口
在端口这一块,我们再来说说复用和分用的概念
- 【复用】:应用进程都可以通过运输层再传送到 IP 层(网络层)
向下
- 【分用】:运输层从 IP 层收到发送给应用进程的数据后,必须分别交付给指明的各应用进程
向上
接下去我们来考虑几个问题
- 进程的创建和撤销都是动态的,因此发送方几乎无法识别其他机器上的进程
- 我们往往需要利用目的主机提供的功能来识别终点,而不需要知道具体实现这个功能的进程是哪一个
- 有时我们会改换接收报文的进程,但并不需要通知所有的发送方
对于上述的这些问题,我们应该怎么去解决呢?没错,就是利用【端口】
- 我们可以在应用层和传输层之间的界面上,设置一个特殊抽象的
门
,有了这个门,应用层中的应用进程就必须通过这个门才能将数据经过运输层发送到互联网;而且别的主机上的应用进程要寻找本主机中的某个某个应用进程,也必须通过这个门(==本段提供对于端口这一概念的理解==) - 我们通常将这个门称做【端口】,每一个端口都有它自己的端口号来进行标识。就好像一台服务器要接收客户机发来的消息,那么它就要从这个端口中去获取信息。
但是对于端口我们要做这么一个区分
👉【硬件端口】:协议栈层间的抽象的协议端口,不同硬件设备进行交互的接口
👉【软件端口】:应用层的各种协议进程与运输实体进行层间交互的地点
- 在后面讲到的TCP和UDP的首部格式中,都有
源端口
和目的端口
这两个重要字段 - TCP/IP的运输层用一个
16位端口号
来标志一个端口
OK就这些,不往下说了,不然太多了,记重点就行
二、用户数据报协议UDP
1、UDP的主要特点
- UDP是无连接的.,可以减少开销和发送数据之间的时延
- UDP是尽最大努力交付
- UDP是面向报文的。程序必须选择
合适大小
的报文。
- 【若报文太长】,UDP就需要分片,这样会==降低IP层的效率==;
- 【若报文太短】,就会使IP数据报的首部相对长度太大【
因为IP数据报的首部字段是固定的
】,也会==降低IP层的效率==
- UDP没有拥塞控制。在一些实用应用(IP电话、实时视频会议等)要求源主机以
恒定的速率
发送数据,但不允许数据有太大的时延,UDP刚好合适 - UDP支持一对一、一对多、多对一和多对多的交互通信
- UDP首部开销小,只有8个字节
2、UDP的首部格式
对于UDP的首部格式,你只需要记住一点,它的首部字段有8个字节,由四个字段组成,每个字段的长度都是2字节
三、传输控制协议TCP概述
学好三、四这两个模块可为后面TCP实现可靠传输打下牢固基础💪
1、TCP的主要特点
- TCP是面向连接(虚连接)的传输层协议
- 每一条TCP连接只能是点对点(一对一)的
- 提供可靠交付的服务
[可靠有序,不丢不重]
- 提供全双工通信
- 【发送缓存】—— 准备发送的数据 & 已发送但尚未收到确认的数据
- 【接受缓存】—— 按需到达但尚未被接受应用程序读取的数据 & 不按序到达的数据
- 面向字节流
面向字节流这一块可能比较抽象,稍微介绍一下
- 从上图可以看出,TCP在发送报文时不关心应用进程一次把多长的报文发送到 TCP 缓存,而是根据对方给出的
窗口值
和当前网络拥塞程度
来决定一个报文段应包含多少个字节,形成TCP 报文段
【这一块在下面会进行再次介绍】
2、TCP的连接
👉TCP把连接作为基本的对象
TCP用主机的IP地址加上主机上的端口号作为TCP连接的【端点】。这样的端点就叫作==套接字==(socket)或插口。套接字用(IP地址:端口号)
来表示
例:套接字 socket = (192.168.1.20 : 7777)
注:
- 同一个IP可以有多个不同的TCP连接;
- 同一个端口号也可以出现在多个不同的TCP连接中
四、可靠传输的工作原理
通过网络层的学习我们可以知道对于IP网络的传输是不可靠的
- 对于实际网络而言都不具备理想传输条件。因此我们必须使用一些可靠传输协议,在不可靠的传输信道实现可靠传输
1、停止等待协议【三次握手雏形】
【停止等待协议】能够在==不可靠传输的网络上实现可靠通信==。对于“停止等待”而言就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组,也就是我们常说的【阻塞队列】
①无差错情况
- 无差错很明显就是传输的时候没有差错,就如下图所示
②出现差错
出现差错有两种情况,对于这两种情况【B 都不会发送任何信息】
- B 接收 M1 时检测出了差错,就丢弃 M1,其他什么也不做
- M1 在传输过程中丢失了,这时 B 当然什么都不知道,也什么都不做
解决方案:==超时重传==
- A 为每一个已发送的分组设置一个
超时计时器
- A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2
- 若 A 在超时计时器规定时间内没有收到 B 的确认,就认为分组错误或丢失,就重发该分组
图示如下
③确认丢失和确认迟到
- ==确认丢失==
- 若 B 所发送的对 M1 的确认丢失了,那么
A 在设定的超时重传时间内将不会收到确认
,因此 A 在超时计时器到期后重传 M1👈 - 假定 B 正确收到了 A 重传的分组 M1。这时 B 应采取【两个行动】:
- 丢弃这个重复的分组 M1,不向上层交付
- 向 A 发送确认(不能认为已经发送过确认就不再发送了)
- ==确认迟到==
- B 对分组 M1 的确认迟到了,因此 A 在超时计时器到期后重传 M1👈
- B 会收到重复的 M1,并且同样要丢弃重复的 M1,并重传确认分组
A 也会收到重复的确认
。对重复的确认的处理:收下后就丢弃,但什么也不做
下面是它们的原理图👇
==通常A总是可以收到对所有发出的分组的确认,如果A不断重传分组但是收不到确认,就说明通信线路太差,不能进行通信==
- 通过上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信,对于这种可靠传输协议就称为
[自动重传请求ARQ]
④信道利用率
- 这一块只需要记住【停止等待协议】的信道利用率太低,中间会有
往返时间RTT
·为了提高传输效率,则不使用低效率的停止等待协议,而是采用【==流水线传输==】
- 对于这个【流水线传输】,就是我们下面要讲的【连续ARQ协议】和【滑动窗口协议】
2、连续ARQ协议【基础要点】
这个协议很重要,【滑动窗口】是后面TCP进行传输原理的重要基石,是TCP协议的==精髓==所在
然后介绍一下这个协议的基本要点
- 发送窗口:发送方维持一个发送窗口,位于发送窗口内的分组都可被
[连续发送出去]
,而不需要等待对方的确认 - 发送窗口滑动:发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置
- 累积确认:接收方对按序到达的最后一个分组发送确认,表示:到这个分组为止的所有分组都已正确收到了
下面是两张原理图
来谈一谈这种【累计确认】
- 优点:容易实现,即使确认丢失也不必重传
- 缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息
五、TCP报文段的首部格式【✔】
接下去我们来说说TCP报文段的首部格式,只有掌握了这些你才能掌握TCP的工作原理:alarm_clock:
==【TCP 首部的最小长度是 20 字节,后面的4N个字节是根据需要而增加的选项】<—— 这点要牢记==
- 【源端口】和【目的端口】:运输层的复用和分用功能通过端口实现
- 【序号】:也叫做报文段序号,表示本报文段所发送的数据的
第一个字节的序号
- 【确认号】:占4个字节,是期望收到对方下一个报文段的第一个数据字节的序号
若确认号 = N,则表明:到序号N - 1为止的所有数据都已正确收到
- 【数据偏移】:指出TCP报文段的数据起始处距离TCP报文段的起始处有多远
以下的这6个字段,在后面有关TCP的三次握手和四次挥手中会频繁使用到
- 【紧急URG】:当
URG = 1
时,表明紧急指针字段有效,告诉系统此报文段中有紧急数据,应尽快传送 (相当于高优先级的数据) - 【确认ACK】:只有当
ACK = 1
时,确认号字段才有效。当ACK = 0
时,确认号无效
- TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1
- 【推送PSH】:当有一段的应用进程希望在键入一个命令后立即就能收到对方的响应,就可以
将PSH置为1
,并立即创建一个报文段发送出去。当接收方收到这个报文段后,就可以尽快地交付接受应用进程,而不再等到整个缓存填满了之后再向上交付 - 【复位RST】:当
RST = 1
时,表明 TCP 连接中出现严重差错(如主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接
- 将RST置为1还可以用来拒绝一个非法的报文段或拒接打开一个连接
- 【同步SYN】
- 当
SYN = 1,ACK = 0
时,表明这是一个连接请求报文段 - 当
SYN = 1,ACK = 1
时,表明这是一个连接接受报文段
- 【终止FIN】:用来释放一个连接。
FIN = 1
表明此报文段的发送端的数据已发送完毕,并要求释放运输连接
虽然是比较多,但是却非常重要,为后面的学习打下坚实的基础💪
- ✔【窗口】:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化
- 一句话 ——>
窗口值作为接收方让发送方设置其发送窗口的依据
- 【检验和】:在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部
- 【紧急指针】:仅在
URG = 1
时才有意义,它指出了本报文段中紧急数据的字节数,因而可以知道紧急数据的末尾在报文段中的位置
- ==即使窗口为0也可以发送紧急数据==
- 【选项】:长度可变,最长可达 40 字节;当没有使用选项时,TCP的首部长度为20字节
👉最后的填充字段仅仅是为了使整个TCP首部长度是4字节的整数倍
六、TCP可靠传输的实现【⭐】
1、以字节为单位的滑动窗口
首先了解一些滑动窗口的概念
- TCP 使用流水线传输和滑动窗口协议实现高效、可靠的传输
- TCP 的滑动窗口是以字节为单位的
- 发送方 A 和接收方 B 分别维持一个发送窗口和一个接收窗口
- 【发送窗口】:在没有收到确认的情况下,发送方可以连续把窗口内的数据全部发送出去。
凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用
- 【接收窗口】:只允许接收落入窗口内的数据
以下是对于发送窗口而言的要点
- A的发送窗口
一定不能超过
B的接受窗口的数值
- 对于发送窗口而言还会受到网络拥塞程度的制约
- 【后沿概念】:已发送且已收到确认
[左边]
- 【前沿概念】:不允许发送,接收方无临时存放的缓存空间
[右边]
- 发送窗口的后沿不能向后移动,因为不能撤销已收到的确认
- 后沿变化情况1:不动
[表示没有收到新的确认]
- 后沿变化情况2:前移
[表示收到了新的确认]
- 发送窗口前沿通常是不断向前移动的,但是也有可能不动
- 前沿不动情况1:对方通知窗口大小不变
[没有收到新的确认]
- 前沿不动情况2:对方通知窗口缩小可
[收到了新的确认]
- 从上图可以看出要描述一个发送窗口的状态需要三个指针:P1、P2 和 P3。下面是三个指针的几个重要意义
P1 = 后沿,P2 = 当前,P3 = 前沿
📚 P1之前的数据 ===》已发送并已收到确认的部分 📚 P3 之后的数据 ===》不允许发送的部分 📚 P3 - P1 ===》A 的发送窗口(又称为通知窗口) 📚 P2 – P1 ===》已发送但尚未收到确认的字节数 📚 P3 – P2 ===》允许发送但尚未发送的字节数(又称为可用窗口)
- 对于接收窗口而言这里便不做细讲,可自行翻阅书本:book:
👇有关窗口滑动的原理方面可以可以看看这个视频,讲解得还不错
[video(video-tUCXoKyo-1674957981501)(type-bilibili)(url-player.bilibili.com/player.html…)]
然后再来谈谈有关发送缓存与发送窗口
发送缓存用来暂时存放
- 发送应用程序传送给发送方TCP准备发送的数据
- TCP已发送出但尚未收到确认的数据
接收缓存用来暂时存放
- 按序到达的、但尚未被接收应用程序读取的数据
- 未按序到达的数据
接下来说说需要强调的三点Ⅲ
- A的发送窗口并不总是和B的接受窗口一样大
[因为有一定的时间滞后]
- TCP 标准没有规定对不按序到达的数据应如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程
- TCP 要求接收方必须有
累积确认
的功能,以减小传输开销。强调两点:
- ① 接收方不应过分推迟发送确认否则会导致发送方不必要的重传;
- ② 捎带确认实际上并不经常发生;
最后强调一点,TCP的通信是全双工通信。通信中每一方都在发送和接收报文段,因此每一方都有自己的发送窗口和接收窗口。在谈到窗口的时候,一定要弄清是哪一方的窗口
2、超时重传的选择
TCP 超时重传时间设置
- ==不能太短==,否则会引起很多报文段的不必要的重传,使网络负荷增大
- ==不能过长==,会使网络的空闲时间增大,降低了传输效率
对上,TCP便采用了一种【自适应算法】,它记录一个报文段发出的时间,以及收到相应确认的时间 这两个时间之差就是报文段的往返时间 RTT
其他考试不会涉及,有兴趣可以看看
3、选择确认SACK
问题:若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?
- 解决:选择确认 SACK (Selective ACK)
- 实现:在建立 TCP 连接时,要在 TCP 首部的选项中加上允许 【SACK 选项】,不过原来首部中的确认号的用法仍然不变
(累积确认)