第三章:传输层

传输层概述

传输层概述

传输层协议为运行在不同主机上的应用进程之间提供逻辑通信功能

传输层协议是在端系统中而不是在网络路由器中实现的

传输层与网络层关系

传输层为运行在不同主机上的进程间的逻辑通信,而网络层则提供了主机之间的逻辑通信

传输层协议所能提供的服务也受到了底层网络层协议的服务模型的限制

因特网传输概述

传输层主要有TCP(传输控制协议)与UDP(用户数据报协议)两种协议,特点及区别如下:

多路复用与多路分解

多路复用与多路分解:本质上是将网络层所提供的主机到主机交付服务,扩展到为在主机上运行的应用程序所提供的进程到进程交付服务

即将从网络层接收的报文段,交付给合适的应用进程

多路复用

从源主机的不同套接字中收集数据块,井为每个数据块封装上首部信息( ( 在多路分解时使用) ) 从而生成报文段,然后将报文段传递到网络层的工作称为多路复用

传输层要达到多路复用,必须保证

  • 套接字有唯一标识符
  • 每个传输层报文段有特殊字段来指示该报文段所要交付的套接字(即源端口号字段与目的端口号字段)

多路分解

将传输层报文段中的数据放置到正确的套接字的工作称为多路分解,确切地说,多路分解其实是多路分发,或者说是数据流的分解。

无连接传输:UDP

UDP 只是做了传输层协议能够做的最少工作。除了多路复用/多路分解功能及少量的差错检测外,它几乎没有对 IP 增加别的东西

UDP发送报文前,发送方与接收方之间并未进行握手,因此UDP是无连接的

DNS即是一个使用UDP的例子,此外音频、视频等通常也使用UDP

UDP的优点

  • 应用层能更好地设置要发送的数据和发送时间(有较快发送速率,且能容忍一些丢包)
  • 无需建立连接(不会引入建立连接的时延)
  • 无连接状态(UDP无连接状态,也无需追踪一些相关参数)
  • 分组首部开销小(TCP有20字节的首部开销,而UDP仅有8个字节)

UDP报文结构

由4个字段组成,每个字段包含2个字节

源端口号、目的端口号

长度:包含首部在内的UDP报文段长度,以字节为单位

校验和:计算报文段在传输的过程中是否出现了差错

校验和

校验和提供了差错检测功能,即当 UDP 报文段从源到达目的时,校验和用于确定其中的比特是否发生了改变

UDP如何实现可靠连接

核心思路:传输层无法保证数据的可靠传输,就通过应用层来实现,实现的方法可以参考TCP以及可靠数据传输的原理

实现确认机制、重传机制、窗口确认机制

可靠数据传输原理(建模)

考虑单向实现可靠传输的建模,得到TCP实现的基本思路

完全可靠信道上

底层信道完全可靠

no bit errors; no loss of packets

1
2
3
4
5
6
7
// 发送方
packet = make_pkt(data) // 生成数据分组
packet = make_pkt(data) // 发送分组

// 接收方
extract (packet,data) // 从分组中提取
deliver_data(data) // 交付数据给应用层

具有比特差错信道上

ACK、NAK不受损

在传输过程中会产生比特差错

需要引入:自动重传请求协议(ARQ),即

  • 差错检测
  • 接收方反馈(ACK:数据包OK;NAK:数据包存在错误)
  • 重传:接收方收到有差错的分组时,发送方进行重传

ACK、NAK受损

确认信息在传输中本身出现错误

解决方法:发送方为数据报添加序号字段,而接收方抛弃重复的数据报

具有比特差错的丢包信道上

除去比特受损外,还有可能丢包

解决方法:发送方等待ACK到来足够的时间(采用定时器实现),然后进行重传

流水线可靠数据传输协议

为提高发送效率(解决上述“停等协议”的问题):以“不停等”方式运行,允许发送方发送多个分组而无需等待确认,该技术称为流水线。流水线提出了新的需求:

  • 必须增加序号范围。保证每个传输的分组有一个唯一的序号
  • 协议的发送方和接收方必须缓存多个分组。
  • 所需序号范围和对缓冲的要求取决于数据传输协议处理丢失、损坏及过度延时分组:回退N步与选择重传

回退N步(GBN)

在 GBN 协议中,允许发送方发送多个分组而不需等待确认,但在流水线中未确认的分组数不能超过某个最大允许数N

已被发送但还未被确认的分组的许可序号范围可以被看成是一个在序号范围内长度为N的窗口,因此N常被称为窗口长度,GBN也被称为滑动窗口协议

当有超时事件发生,出现丢失和过度时延分组时,发送方将重传所有已发送但还未被确认的分组

GBN使用了累积确认技术,累积确认指接收一个未出错分组(可能失序)时总是返回一个最后接收的按顺序到达分组的确认。

选择重传

选择重传 (SR) 协议通过让发送方仅重传那些它怀疑在接收方出错的分组而避免了不必要的重传。

这种个别的、按需的重传要求接收方逐个地确认正确接收的分组,也用窗口长度N来限制流水线中未完成、未被确认的分组数。

面向连接的传输:TCP

TCP是面向连接的传输层协议,连接的实质是双方都初始化与连接相关的发送/接收缓冲区,以及许多 TCP 状态变量

  • TCP连接提供的是全双工服务
  • TCP连接是点对点的(TCP不可能多播)

TCP连接每一端都有各自的发送缓冲和接收缓存,TCP 可从缓存中取出并放入报文段中发送的数据量受限于最大报文段长MSS(Maximum Segment Size),通常由最大链路层帧长度(即最大传输单元MTU)来决定(也就是底层的通信链路决定)

除去进行通信的两台主机之中维护TCP连接所需的内容,这两台主机之间的路由器交换机并未为该连接分配任何缓存和控制变量

TCP报文格式

  • 源端口号与目的端口号:用于多路复用/多路分解来自或送至上层应用的数据
  • 32 比特的序号字段和 32 比特的确认号字段:用来实现可靠数据传输服务

序号字段:即该数据报在所需传送的字节流上的位置,用于实现TCP报文的有序性

确认号字段:用于标识接收方期待从发送方收到的下一报文段首字节的序号

  • 16 比特的接收窗口字段:用于流量控制,用于指示接受方能够接收的字节数量
  • 4 比特的首部长度字段:用于指示以 32 比特的字为单位的 TCP 首部长度,一般 TCP 首部的长度就是 20 字节
  • 6比特标志字段:主要使用以下三个

ACK:用于指示确认字段中的值是有效的(对成功接收报文的确认),ACK=1时有效

SYN:表示建立一个连接

​ SYN=1,ACK=0时,表示这是一个连接请求报文段

​ SYN=1,ACK=1时,表示对方同意建立连接

FIN:告知对方关闭连接

三次握手

第一次握手

发送方创建一个特殊的TCP报文段(SYN报文段):

  1. 不包含任何应用层数据;
  2. 将SYN标志位置为1;
  3. 随机生成一个初始序号(client_isn),并将该序号置于该报文的序号字段(seq)处

第二次握手

收到SYN报文段后,接收方会返回允许连接的报文段(SYNACK报文段):

  1. SYN标志位置为1,ACK标志位置为1;
  2. 确认号字段(ack)置为client_isn+1;
  3. 接收端生成一个自己的初始序号(server_isn),并将该序号置于自己报文的序号字段(seq)处

第三次握手

RFC793文档里说明带有SYN标志的过程包是不可以携带数据的,因此三次握手的前两次是不能携带数据的

而第三次握手运行携带数据

  1. SYN被置为0,ACK置为1
  2. 确认号字段置为server_isn+1
  3. seq字段设置为client_isn+1

异常情况

  • 第一次握手丢失:会触发超时重传(重传3此syn包,每次间隔一定时间)
  • 第二次握手丢失:会触发情况1,同时服务器也会进行超时重传(每次间隔一定时间),收到客户端的syn报文会立即回复
  • 第三次握手丢失:此时客户端已经进入 ESTABLISHED 状态,而服务器仍然处于 SYN-RCVD 状态。此时服务器接收到客户端发送过来的数据会判断连接已经建立,并进入 ESTABLISHED 状态。

参考:https://blog.csdn.net/plokmju88/article/details/103884145

四次挥手

  1. 主机A发送一个用来释放连接的报文(标识了FIN=1,序列号seq=a,ack=z,),并处于FIN-WAIT-1状态,此处A不再有数据发送,但仍然可以接收数据
  2. 主机B回应一个标识了ACK=1的数据段,序列号seq=b,确认序号ack=a+1,作为对主机A的FIN报文的确认,并且进入CLOSE-WAIT状态。A收到确认后,进入FIN-WAIT-2**状态**,等待B的连接释放报文段
  3. 主机B向主机A发送一个标识了FIN=1,ACK=1的数据段,序列号为seq=b,确认序列号为ack=a+1,用以释放连接
  4. 主机A发送标识了ACK=1,序列号seq=a+1,确认序号ack=b+1,用以确认关闭

客户端或服务器均可主动发起挥手动作

为什么要进行四次挥手(CLOSE_WAIT状态的意义)

因为TCP是全双工模式,一方发送FIN报文只是代表单方面没有信息需要发送了,但另一方可以继续发送报文,只有双方都发送了FIN报文整个通信过程才能结束

TCP释放连接为何发送方TIME_WAIT状态必须等待2MSL的时间

MSL(Maximum Segment Lifetime):报文段最大生存时间,任何报文在网络上存在时间超过该时间就会被丢弃

  • 为了保证A发送的最后一个ACK报文能够到达B,从而可靠地实现TCP全双工连接的终止

    由于该ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,因此会引起超时重传。而若A不等待而是直接释放连接,就无法收到B重传的FIN报文段,就不会再发送一次确认报文段,最终会导致B无法按照正常的步骤进入CLOSED状态

  • 允许老的报文在网络中消逝

    经过2MSL时间,可以使本次连接所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现旧的连接请求的报文段(彻底完成这次报文的发送与接收

大量TIME_WAIT造成的影响

tcp中TIME_WAIT状态的危害

TCP可靠数据传输

主要有超时重传和快速重传:

  • 超时重传:超时后进行重传,需要设置超时事件(通常4个往返时间RTT)
  • 快速重传:如果发送者收到了重复的3个ACK报文段(接收方如果发现有丢失(即收到了间隔后的报文段)会重复发送ACK报文段,),说明该报文段所指下一个段丢失,会在超时触发前快速重传该报文段。可以避免超时引起的大时延

延迟确认机制

接收方在收到数据后,并不会立即回复ACK,而是延迟一定时间(通常每200ms检查一次)

目的:

  • ACK是可以合并的,也就是指如果连续收到两个TCP包,并不一定需要ACK两次,只要回复最终的ACK就可以了,可以降低网络流量
  • 如果接收方有数据要发送,那么就会在发送数据的TCP数据包里,带上ACK信息。这样做,可以避免大量的ACK以一个单独的TCP包发送,减少了网络流量

TCP流量控制——滑动窗口

流量控制只要在于消除发送方导致接收方缓存溢出的可能性(避免因为接收方缓存区满而造成的大量丢包的问题),流量控制是一个速度匹配服务,即发送方的发送速率与接收方应用程序的读速率相匹配

TCP通过维护报文中接收窗口字段来提供流量控制,接收窗口用于告诉发送方,该接收方还有多少可用的缓存空间

发送方的发送窗口大小不能超过接收方给出窗口大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据

实现方法

报文中有的窗口字段表示窗口的大小,请求和响应窗口大小一增一减表示窗口的滑动
$$
发送窗口 = min(拥塞窗口, 接收窗口)
$$

拥塞控制原理

产生拥塞的情况

情况1

两个发送方和一个具有无穷大缓存的路由器

当分组到达速率接近链路容量时,分组将经历较长的排队时延

情况2

两个发送方和一个具有有限缓存的路由器

发送方在遇到大时延时所进行的不必要重传,导致路由器需要利用其链路带宽来转发不必要的分组

情况3

四个发送方、具有有限缓存的多台路由器和多跳路径

当一个分组沿一条路径被丢弃时每个上游路由器用于转发该分组而使用的传输容量最终被浪费掉了

拥塞控制方法

端到端控制

网络层没有为传输层拥塞控制提供显式支持,因此端系统必须对网络行为观察(分组丢失、时延等),来推断拥塞的发生

TCP中将报文段的丢失(通过超时或3次冗余确认得知),认为是网络拥塞的一个迹象,之后TCP会相应减小其发送的窗口

网络辅助的拥塞控制

网络层对是否产生拥塞显式反馈给端系统

TCP拥塞控制

由于IP向端系统提供显式的网络拥塞反馈,因此TCP必须使用端到端的拥塞控制

拥塞控制的过程是源主机不断试探网络传输能力的过程,如果一个TCP发送方没有感知到拥塞,它就会增加其发送速率;如果感知到拥塞,则降低其发送速率

TCP拥塞控制机制使用一个控制变量,即拥塞窗口(congestion window)来表征网络的拥塞情况

发送窗口 = min{CongWin, RcvWin}

加性增,乘性减

  • 加性增:每个RTT周期CongWin增加1个MSS单位,直到检测到丢包
  • 乘性减:当检测到丢包时,CongWin减半

慢启动

在慢启动阶段,每当一个传输的报文段被确认后,CongWin 的值就增加1个 MSS ,由于TCP 一次发送多个报文段进入网络,从
而使发送方的发送速率在经过一个 RTT 时间后成倍增长

以指数级增长后,直到遇到一个丢包,CongWin减半后开始变为线性增长

对超时事件的反应

  1. 收到3个冗余ACK后,TCP将拥塞窗口减小一半,然后线性增长
  2. 超时事件发生后,TCP则进入一个慢启动状态

TCP通过维持一个称为阈值 (Threshold) 的变量来确定慢启动将结束并且拥塞避免将开始的窗口长度

变量Threshold初始化时被设置为一个很大的值,每当发生一个丢包事件时,Threshold值就会被设置为当前CongWin值的一半

总结

  • 慢启动:CongWin < Threshold,CongWin指数增长
  • 拥塞避免:CongWin > Threshold,CongWin线性增长
  • 快速恢复:3个冗余ACK,Threshold设置为Threshold/2,CongWin设置为Threshold
  • 超时处理:timeout事件,Threshold设置为Threshold/2,CongWin设置为1MMS大小

参考:

https://zhuanlan.zhihu.com/p/145260638

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2019-2021 子夜
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信