文章目录
五层协议之传输层
一、传输层概述
1. 传输层的功能
当网络的边缘部分中的两个主机使用网络的核心部分的功能进行端到端的通信时,只有位于网络边缘部分的主机的协议栈才有传输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。
-
传输层为应用进程之间提供端到端的逻辑通信(但网络层是为主机之间提供逻辑通信)。
-
传输层还要对收到的报文进行差错检测。
-
传输层需要有两种不同的运输协议,即面向连接的
TCP和无连接的UDP。
2. 两个主要协议
(1) 用户数据报协议 UDP (User Datagram Protocol)
(2) 传输控制协议TCP (Transmission Control Protocol)
-
UDP 在传送数据之前不需要先建立连接。对方的传输层在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 是一种最有效的工作方式。如局域网广播、域名解析。
-
TCP 则提供面向连接的服务。TCP 不提供广播或多播服务。由于 TCP 要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。
3. 端口
1)产生背景
端口为什么会产生?
我们知道,计算机的每个进程都有一个进程标识符(PID)。如果一个进程p给一个计算机A发请求,计算机A发送的答复数据也该由这个进程p负责处理,但是进程的创建和销毁都是动态的,导致发送方A无法确认这个答复包要交给目的计算机的哪个进程处理。而且有时我们会改换接收方的进程号,但并不需要通知所有发送方。
解决这个问题的方法就是在传输层使用协议端口号(protocol port number),或通常简称为端口(port)。
虽然通信的终点是应用进程,但我们可以把端口想象是通信的终点,因为我们只要把要传送的报文交到目的主机的某一个合适的目的端口,剩下的工作(即最后交付目的进程)就由 TCP 来完成。
区分软件端口和硬件端口:
在协议栈层间的抽象的协议端口是软件端口。
路由器或交换机上的端口是硬件端口。如Serial端口。
硬件端口是不同硬件设备进行交互的接口,而软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。
2)TCP端口
端口用一个 16 位端口号进行标志。
端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程。在因特网中不同计算机的相同端口号是没有联系的。
3)三类端口(了解)
-
熟知端口,数值一般为
0~1023。 -
登记端口号,数值为
1024~49151,为没有熟知端口号的应用程序使用的。使用这个范围的端口号必须在 IANA 登记,以防止重复。 -
客户端口号或短暂端口号,数值为
49152~65535,留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。
二、用户数据报协议UDP
1. UDP的特点
虽然 UDP 用户数据报只能提供不可靠的交付,但 UDP 在某些方面有其特殊的优点。
-
UDP 是无连接的,即发送数据之前不需要建立连接。
-
UDP 使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制。
-
UDP 支持一对一、一对多、多对一和多对多的交互通信。
-
UDP 的首部开销小,只有
8个字节。
2. UDP的首部格式
源端口、目的端口表示发送进程和接受进程。
长度指的是UDP首部和UDP数据的字节长度。
检验和的计算需要用到IP首部的部分信息,称之为伪首部。与UDP首部拼接在一起然后求和取反得到检验和。
计算完检验和后将伪首部丢弃。
三、传输控制协议TCP介绍
1. TCP的特点
-
TCP 是面向连接的传输层协议。
-
每一条 TCP 连接只能有两个端点(endpoint),每一条 TCP 连接只能是点对点的(一对一)。
-
TCP 提供可靠交付的服务。
-
TCP 提供全双工通信。
-
面向字节流。
2. TCP的连接端点
TCP 连接的端点不是主机,不是主机的IP 地址,不是应用进程,也不是传输层的协议端口。TCP 连接的端点叫做套接字(socket)或插口。端口号和IP地址拼接构成了套接字。
四、可靠传输的工作原理
1. 可靠传输的四种情况
这种可靠传输协议常称为自动重传请求ARQ(Automatic Repeat reQuest)。
还有一种情况是,当A发M1给B,B收到了,但B的回复包阻塞了。A等一段时间后于是重发M1, 这个M1中途丢了。但之前那个阻塞的回复包送达了A。此时A认为B收到了重传的M1,实际上重传的M1丢了。
但这没有任何影响,因为B保存了A第一次送达的M1。
2. 信道利用率
U为信道利用率,为发送分组耗时,RTT为发完分组到接收确认信息耗时,表示确认耗时。
3. 流水线传输
为了提高信道利用率,发送方可以一次连续发送多个分组,不必每次发送一个分组就停下来等待确认。
这种通信方式信道利用率很高。
4. 连续ARQ协议
发送方维护一个指定长度的滑动窗口。首先将窗口内的包都发出去,如果收到确认信息后,就向右移动窗口,继续发送未发送的包。
比如这里先发1 - 5,然后1收到了,滑动窗口右移一格,继续发6。
接收方也不需要每个包都发确认信息,而是对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了。这个也叫做累计确认。
如果发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。按照上面的确认方法,这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。
这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N 个分组。
可见当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。
五、TCP报文首部格式
源端口/目的端口:字面意思,各占 2 字节。说明端口的最大范围是 ~ 。
序号:4字节。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
确认号:4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。
数据偏移:4位(每单位4字节)。记录了TCP数据部分距离TCP起始处多远,也是首部长度。
保留字段:占 6 位,保留为今后使用,但目前应置为 0。
URG(Urgent):当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
ACK(Acknowledgment):有当 ACK = 1 时确认号字段才有效。当 ACK = 0 时,确认号无效。
PSH(Push):当PSH = 1的数据包被接收时,会直接推送到对应进程,无视接收缓冲区。
RST(Reset):当 RST = 1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
SYN(Synchronization):同步 SYN = 1 表示这是一个连接请求或连接接受报文。
FIN(Final):用来释放一个连接。FIN = 1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
窗口:记录自己的接收窗口大小,让对面设置相同大小的发送窗口。
检验和:检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。
紧急指针:记录TCP数据部分紧急部分到那里结束,如果紧急指针为50,就代表数据部分0 ~ 50是紧急部分(紧急数据放在本报文段数据的最前面)。
选项:TCP 最初只规定了一种选项,即最大报文段长度 MSS。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”
六、TCP可靠通信的具体实现
1. 缓存和窗口
发送方和接收方分别有一个发送窗口和一个接收窗口。这两个窗口的大小在建立连接时就互相确定了,根据对方的接收窗口大小给自己设置同样大小的发送窗口。
发送缓存用来暂时存放:
-
发送应用程序传送给发送方 TCP 准备发送的数据;
-
TCP 已发送出但尚未收到确认的数据。
接收缓存用来暂时存放:
-
按序到达的、但尚未被接收应用程序读取的数据;
-
不按序到达的数据。
2. 重传时间的选择(了解)
重传机制是 TCP 中最重要和最复杂的问题之一。
TCP 每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段。
由于 TCP 的下层是一个互联网环境,IP 数据报所选择的路由变化很大。因而传输层的往返时间的方差也很大。
所以,只以一次的往返时间作为重传时间是不可行的。
于是TCP 保留了 RTT 的一个加权平均往返时间 (这又称为平滑的往返时间)。
第一次测量到 样本时, 值就取为所测量到的 样本值。以后每测量到一个新的 样本,就按下式重新计算一次 :
式子的 越接近0,说明旧的值权重越大。越接近1,说明新值的权重越大。
RFC 2988 推荐的 值为 1/8,即 0.125。
有了上面的后,超时重传时间 (RetransmissionTime-Out)应略大于上面得出的加权平均往返时间 。
为RTT 的偏差的加权平均值。
3. 选择确认SACK
之前说过累计确认,表示目标字节之前的都收到了。但累计确认存在的问题是,当其中一个片段没收到,后面的所有内容(发送窗口内)需要重新发送。
所以SACK就是解决这个问题的,SACK能告诉发送方缺失哪一个片段的内容,然后发送方只需要重发那一个片段的内容即可。
如果要使用选择确认,那么在建立 TCP 连接时,就要在 TCP 首部的选项中加上“允许 SACK”的选项,而双方必须都事先商定好。
如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。只是以后在 TCP 报文段的首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。
由于首部选项的长度最多只有 40 字节,而指明一个边界就要用掉 4 字节,因此在选项中最多只能指明 4 个字节块的边界信息。
七、TCP流量控制
流量控制(flow control)就是让发送方的发送速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。
接收端在每次发送确认信息时,会带上自己的接收窗口大小。然后发送端会即使调整自己的发送窗口大小
八、TCP拥塞控制
在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生拥塞(congestion)。
流量控制是端到端之间的,发送端到接收端的通信量控制。而拥塞控制涉及到所有的主机、所有的路由器等等影响网络的因素。
那么怎么解决拥塞问题呢?
发送方维持一个叫做拥塞窗口 cwnd (congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
1. 慢开始和拥塞避免
在主机刚刚开始发送报文段时可先设置拥塞窗口 cwnd = 1,即设置为一个最大报文段 MSS 的数值。
-
使用慢开始算法后,每经过一个传输轮次,拥塞窗口 cwnd 就加倍。
-
传输轮次所经历的时间其实就是往返时间 RTT。
-
“传输轮次”更加强调:把拥塞窗口 cwnd 所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。
当出现拥塞时:
慢开始门限 ssthresh 的用法如下:
-
当 时,使用慢开始算法。
-
当 时,停止使用慢开始算法而改用拥塞避免算法。
-
当 时,既可使用慢开始算法,也可使用拥塞避免算法。
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢地增大,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是加倍,使拥塞窗口 cwnd 按线性规律缓慢增长。
**“乘法减小“**是指不论在慢开始阶段还是拥塞避免阶段,只要出现一次超时(即出现一次网络拥塞),就把慢开始门限值 ssthresh 设置为当前的拥塞窗口值乘以 0.5。
当网络频繁出现拥塞时,ssthresh 值就下降得很快,以大大减少注入到网络中的分组数。
**“加法增大”**是指执行拥塞避免算法后,在收到对所有报文段的确认后(即经过一个往返时间),就把拥塞窗口 cwnd增加一个 MSS 大小,使拥塞窗口缓慢增大,以防止网络过早出现拥塞。
2. 快重传和快恢复
快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方。
发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段。
-
当发送端收到连续三个重复的确认时,就执行“乘法减小”算法,把慢开始门限
ssthresh减半。但接下去不执行慢开始算法。 -
由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,即拥塞窗口 cwnd 现在不设置为 1,而是设置为慢开始门限 ssthresh 减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。
九、TCP连接管理
1. 连接的三个阶段
-
传输连接就有三个阶段,即:连接建立、数据传送和连接释放。传输连接的管理就是使传输连接的建立和释放都能正常地进行。
-
连接建立过程中要解决以下三个问题:
-
要使每一方能够确知对方的存在。
-
要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。
-
能够对传输实体资源(如缓存大小,连接表中的项目等)进行分配。
TCP 连接的建立都是采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client)。被动等待连接建立的应用进程叫做服务器(server)。
2. 建立连接
A 的 TCP 向 B 发出连接请求报文段,其首部中的同步位 SYN = 1,并选择序号 seq = x,表明传送数据时的第一个数据字节的序号是 x。
B 的 TCP 收到连接请求报文段后,如同意,则发回确认。
B 在确认报文段中应使 SYN = 1,使 ACK = 1,其确认号ack = x + 1,自己选择的序号 seq = y。
A 收到此报文段后向 B 给出确认,其 ACK = 1,确认号 ack = y + 1。
A 的 TCP 通知上层应用进程,连接已经建立。
B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。
根据这三次握手,建立TCP连接的各状态。
3. 释放连接
数据传输结束后,通信的双方都可释放连接。现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。
A 把连接释放报文段首部的 FIN = 1,其序号seq = u,等待 B 的确认。(A:我要杀你了)
B 发出确认,确认号 ack = u + 1,而这个报文段自己的序号 seq = v。
TCP 连接处于半关闭状态。B 发送最后的一些数据(B:等等、我写点遗嘱),A 仍要接收。
B的遗嘱发送完后,就向A发送FIN=1的数据。(B:遗嘱写完了,动手吧)
A 收到连接释放报文段后,必须发出确认。(A:那我动手了)
以上为整体生命周期。