运输层为它上面的应用层提供通信服务,位于网络的边缘部分,当位于网路边缘的两台主机使用网络的核心部分进行端到端通信时,只有主机的协议栈才有运输层,而网路核心部分中的路由器在转发分组时只用到下三层的功能。
在 IP 层中,因为 IP 首部标记的是主机,所以说通信是 “两台主机之间的通信” ,但是我们都知道一台主机可以干很多事情的,比如说可以一边聊微信,一边用浏览器看网页,不同的工作之间是不会相互干扰的,这些互不干扰的工作就是进程,而我们在聊微信时,应该是微信的进程想另一台主机的微信进程进程了通信,所以说通信的严格说法是 “两台主机中的应用进程通信”。
运输层的工作就是为主机中的应用进程提供通信服务,而网络层是为主机提供通信服务,当用户进程发送信息时,应用层会发送进程的数据到运输层,而网络层传输的数据是整个主机的杂合在一起的数据,所以运输层必须在交付数据给网络层之前把各个应用进程的数据都整合起来,我们称这为复用;而对于接受方主机,在运输层中接收到了网络层传来的杂合数据,它在交付数据给应用层之前必须要把这些杂合的数据分开为各个进程的数据。
运输还要对收到的报文进行差错检测,在网络层,IP 层数据报首部中检验和字段,只检验首部是否出现差错而不检测数据部分。
用户数据报协议 UDP运输协议数据单元: UDP 用户数据报
UDP 在传送数据之前不需要先建立连接。远地主机的运输层在收到 UDP 报文后,不需要给任何确认。
UDP 只在 IP 的数据报服务之上增加了很少一点的功能,这就是复用分用的功能以及差错检测的功能。
特点- 无连接,在发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
- 使用尽量大努力交付,即不保证可靠交付,因此主机不需要不需要维持复杂连接状态表
- 面向报文。发送发的 UDP 对应用层交下来的报文,在添加首部后就向下交付 IP 层
- 没有拥塞控制
- 支持 一对一,一对多,多对一,多对多的交互通信
- UDP 的首部开销小,只有8个字节,比 TCP 的 20 个字节的首部要短。
- 面向连接。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接。
- 每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点。
- 提供可靠交付(交付给应用层)的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达。
- TCP 提供全双工通信。TCP 允许通信双方的应用进程在任务时候都能发送数据。 TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据
- 面向字节流。 TCP 中的流 (stream)指的是流入到进程或从进程流出的字节序列。
分组时串行发送,发送完一个分组,停止发送,收到接受方的确认后才会发送下一个分组,否则就会超时,重新发送上一个分组。串行发送,效率低下。
连续ARQ 协议为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输协议。发送可以连续发送多个分许,不必每发完一个分组就得停顿夏利等待对方的确认。连续 ARQ 协议就是一种流水线传输协议。
工作原理:发送方使用滑动发送窗口维持每次发送多个分组,滑动窗口的随着传输的进行,不断的向前移动。接受方也有一个检验接受分组的接收窗口,负责维持分组的次序,差错检测,分组确认,分组缓存。
以字节为单位的滑动窗口 发送窗口- 发送窗口的大小受接收窗口大小和当时网络拥塞程度的共同制约。接收方确认分组时会附带当前接收窗口大小(表示当前接收数据的能力),网络拥塞控制也会限制发送方的拥塞窗口。
- 发送窗口的位置由前沿(上图的右边)和后沿(上图左边)的位置共同制约。后延的变化:不动(没有收到新确认)和前移(收到新的通知),后延不会后移,因为不能撤销掉已收到的确认。前沿的变化:前移(收到新确认或窗口变大),不动(没有收到新确认且窗口大小不变、收到新确认,窗口变小),后移(窗口变小)。
发送方的应用进程把字节流写入 TCP 的发送缓存,接收方的应用进程从 TCP 的接受缓存读取字节流。
发送缓存发送缓存存放:
- TCP 准备发送的数据
- TCP 已发送但未确认的数据
发送窗口只是发送缓存的一部分。已被确认的数据会从缓存中立即删除,发送窗口的后沿与发送缓存的后沿重叠
接收缓存存放:
- 按序到达的、但尚未被接收应用程序读取的数据
- 未按序到达的数据
如果收到的分组被检测出差错,则要丢弃。如果接收应用程序来不及读取收到的数据,接收缓存最终会被填满,使接收窗口减小到零。反之,如果接收程序能及时读取收到的数据,接收窗口就增大。
TCP 流量控制一般来说,我们总是希望数据传输得更快一些。但如果发送方把数据发得过快,接收方就可能来不及接收,这就会造成数据的丢失。所谓流量控制(flow control )就是让发送方的发送速率不要太快,要让接收方来的及接收。
利用 滑动窗口的机制就可以很方便的在 TCP 连接上实现对发送方的流量控制。
TCP 拥塞控制 什么是拥塞?在计算机网络中链路容量(即带宽)、交换节点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞。
TCP 拥塞控制会有一个拥塞窗口 cwnd,该窗口反应了当前网络的资源的可以部分大小,资源越多,拥塞窗口能到达的最大值就越大,而拥塞窗口会影响发送方的发送窗口大小一种因素,为了方便研究拥塞控制,我们假定发送窗口大小就是拥塞窗口大小。拥塞窗口是以字节为单位的,下面以报文段为单位。拥塞控制就是通过控制拥塞窗口,进而控制往网络发送资源的发送方(多个)的发送窗口,从而让网络保持在一个相对稳定的运行状态。
慢开始 设计思路当主机开始发送数据时,由于并不清楚网络的负载情况,所以如果立即把大量数据字节注入到网络,那么就有可能引起网络发送拥塞。经过证明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,有小到大逐渐增大拥塞窗口数值。
过程- 主机一开始设置拥塞窗口 cwnd 的大小为 1至2个发送方的最大报文段 SMSS (Sender Maximun Segment Size) 的数值,新版的 RFC 5681把初始拥塞窗口设置为不超过 2至 4个 SMSS 的数值。
- 在每收到一个对新的报文段的确认后,拥塞窗口增加最多一个 SMSS 的数值,即 拥塞窗口最多会增大一倍。因此每经过一个传输轮次,拥塞窗口就会加倍。
ps: 在慢开始中,控制窗口的大小并不是一下子增大一倍的,而是慢慢的增大,最终增大一倍。一个拥塞窗口包含多个报文段,发送方每收到一个报文段的确认,窗口就增加该报文段的长度,当上一次的报文段都被接收完后,此时的窗口恰好相比之前增加了一倍。
拥塞避免为了防止拥塞窗口 cwnd 增大过大引起网络的拥塞,还需设计一个慢开始门限 ssthresh 状态变量。
- 当 cwdn < ssthresh, 使用 慢开始算法
- 当 cwdn > ssthresh, 使用拥塞避免算法
- 当 cwdn = ssthresh, 即可以使用慢开始算法也可以使用拥塞避免算法
让拥塞窗口缓慢增大,即每经过一个往返时间 RTT 就会把发送的拥塞窗口加一,而不像慢开始阶段那样加倍增长。因此在拥塞避免阶段就有 “加法增大” AI (Additive Increase) 的特点。这表明在拥塞避免阶段,拥塞窗口按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
ps: 在拥塞避免中,每个轮次拥塞窗口的大小也不是一下子增加1个报文段的数值的,实例上,拥塞窗口是以字节为单位,仅增加一个 MSS 的大小,单位是字节。只要收到一个新的确认,就把拥塞窗口 cwnd 增加 (MSS * MSS / cwnd)个字节。例如,假定 cwnd 等于 10 个 MSS 的长度,而 MSS 是 1460 字节。发送方可一连发送 14600 字节 (即10个报文段)。假定接收方没收到一个报文段就发回一个确认。于是就稍微增大一些,即增大 0.1 ms = 146 字节。经过一个往返时间 RTT,发送方共收到 10 个新的确认,拥塞窗口就增大了 1460 字节,正好是一个 MSS 的大小
快重传 设计思路快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文也要立即发送对已收到的报文段的重复确认。当发送方一连收到3个重复确认,就知道接收方确实没有收到某一报文段,因而应当立即重传(快重传),这样就不会出现超时,发送方也不会误认为出现了网络拥塞。使用快重传可以使整个网络的吞吐量提高约 20%。
快恢复当发送方知道丢失了个别的报文段,启动了快重传后,不启动慢开始,而是执行快恢复算法。这时,发送方调整门限值 ssthresh = cwnd / 2, 同时设置拥塞窗口 cwnd = ssthresh,并开始执行拥塞避免算法。
TCP 三报文握手 连接 (三次握手)TCP 建立连接的过程叫做握手,握手需要在客户和服务器端之间交换三个 TCP 报文段
过程: 简化版:- 客户发送 连接同步 请求 TCP 报文段给服务器端
- 服务器发送 同步连接 成功响应 TCP报文段
- 客户发送 已收到服务器端响应 并 告知开始发送数据 TCP 报文段
- 客户端主动向服务端发送 TCP 请求报文段,同步为 SYN 置为 1,随机生成一个序列号 seq = x
- 服务器收到请求后返回一个 TCP 确认报文段,同步位 SYN 和 确认位 ACK 置1, 随机生成一个 序列号 seq = y,确认号 ack = x + 1
- 客户端收到服务器的返回 TCP 确认报文段后,确认位 ACK 置 1,序列号 sep = x + 1, 确认号 ack = y + 1
让客户端和服务器端知道双方的序列号,不是只需要两个报文段就能实现了吗?为什么要三次呢?
两种说法- 确保服务器和客户端都知道对方的序列号(序列号用于确保数据传输的次序),第一个报文段是服务器知道客户端的序列号,第二个报文段是客户端知道服务器端的序号,并告知服务端已知道客户端序号,第三个报文段是告知客户端已知道服务器端的序列号。
- 防止已失效的连接请求报文段突然又传送到服务器端(谢希仁计算机网络)。如果客户端发送第一个连接请求报文段时由于某些原因发生了滞留,又重发了一次并双方建立了连接,传输完数据后断开了连接。如果这时,滞留的第一个连接请求报文段到达了服务器端,服务器误认为客户端又重新发起连接请求,返回确认报文,并打开了等待数据传输进程,可是客户端并没有再次发送连接请求,就不会理睬服务器端的确认,这造成服务器端白白等待,浪费资源。
数据传输结束后,需要释放 TCP 连接,与连接建立只能客户端发起连接不同,释放连接可以由任意双方发起,下面以客户端发起为例。
过程 简化版- 客户端发送完数据或就发送一个释放报文段告诉服务器我发送完数据了,我们可以断开连接了。
- 服务器端收到请求后会立即告诉客服端,我收到你的断开请求了,但你要等我也发完数据。
- 服务器端处理完数据之后,发送实发报文段给客户端,我数据处理完毕了,我们断开连接吧。
- 客户端收到服务端的释放报文段后给服务器一个确认报文段,等待 2MSL 后进入 close 状态
- 客户端向服务器端发送释放报文段,并停止发送数据。在报文段首部,将终止控制位 FIN 置1, 设置序列号为 u (u 等于自己前面已传送过的数据的最后一个字节的序号加 1)
- 服务器端收到客户端的释放报文段后立即发出确认,确认号 ACK 为 u + 1, 设置序列号 为 v (v 等于自己前面已传送过的数据的最后一个字节的序号加 1),服务器端进入半关闭状态
- 当服务器端不需要发送数据时,向客户端发送释放报文段,将终止控制 FIN 置1,设置序列号 为 w (w 等于在半关闭状态已传送的数据最后一个字节的序号加 1),重复设置确认号 ACK 为 u + 1,服务器端进入最后确认状态。
- 客户端收到服务器发送的释放报文段后,必须对此发出确认。报文段总把 ACK 置 1, 确认号 ACK为 w + 1, 确认号为 u + 1, 等待 2SML (最长报文段寿命)
最后客户端发送完释放确认报文段,不是可以直接连接关闭状态了吗?为什么还要等待 2MSL?
两个原因- 报文段可能在发送的过程中丢失,服务器端没收到端的确认报文段,会超时重传结束连接报文段,如果客户端发送完确认报文就进入关闭状态,那么服务器就一直拿不到客户端的确认报文段,白白浪费资源。
- 保证在本次连接过程中的所有报文段从网络中消失,不会影响到下一次连接。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)