传输层介绍

59 阅读11分钟

传输层实现应用进程之间的逻辑通信,仿佛两个应用进程是直接通信的,不关心两台主机之间距离多少物理距离。

发送方:将应用递交的信息分成一个或多个Segment,并向下传给网络层

接收方:将收到的Segement组装成消息,并向上交给应用层。

传输层可以为应用提供多种协议: Internet上的TCP、UDP

TCP 提供可靠传输服务 UDP 提供尽力而为的传输服务

多路复用、多路分用

由于应用进程存在多个当共同使用一个协议时就需要将消息分发到对应不同的应用进程(将消息转发给不同的socket,应用层与网络层的接口),即多路分用。当发送消息时传输层需要为每个不同的应用进程发出的消息封装上不同的头部信息从产生不同正确的报文段(Segement)交给网络层,即多路复用。

面向无连接的复用和分用UDP为例子

使用两元组标识,目的端口号、源端口号

通过目的端口号传输层会发送到对应socket,传输层通过源端口号可以封装返回的IP数据报给网络层。

面向连接的复用和分用TCP为例子

使用四元组标识:源IP地址、源端口号、目的IP地址、目的端口号

由于TCP与UDP对于socket的链接方式不同,TCP需要通过源IP地址、源端口号、目的IP地址、目的端口号来确定一个唯一的socket因此再复用和分用上也产生了与UDP不同的区别

可靠数据传输(Rdt)

可靠数据传输的内容不仅在传输层涉及在其他层可以适用。

何为可靠。不错、不丢、不乱。即,内容不发生错误、数据报不丢失、数据包到达的顺序不错乱。

实现可靠数据传输的内容包括:

  1. 差错检测,通过发送的内容计算出附加信息,用于差错检测即差错编码(如校验和)。
  2. 确认,接收方的反馈确认,数据是否正确。是的话响应发送发ACK,否则响应NAK。
  3. 重传,如接收方响应NAK需要将对应序列的数据报重传。
  4. 序号,标识数据报的顺序
  5. 计时器,如数据包丢失超时重传

停-等协议

发送方发送一个消息后,需要等待接收方确认,才能继续发送下一个消息。

可靠信道上的数据传输 rdt 1.0

无需任何可靠数据传输机制

产生位错误的信道 rdt 2.x

校验和(消息的和ACK的)+确认机制+序列号+重传

ack 永远确认最后一个被正确接收的消息 引入确认机制,在停等协议中,一般只使用ACK,不使用NAK,这样可以减少数据包的类型,降低复杂度。那么当接收方检测出数据错误如何告知发送方呢。只需要对ACK进行一定的改造,例如接收方期待接收序号为0的ACK,此时发送方响应序号为0的ACK,接收方照常发送下一个消息。如果响应的ACK中要求的序号不为0,发送方期待却ACK 0,此时发送方就会将该序号的消息重传。

可能发生丢失分组 rdt 3.0

加入定时器 等待一个合理的时间之后,还未收到响应,则发送方重传

性能分析

停等协议由于需要等待成功响应之后才能发送下一个分组,因此性能很差。

image.png

滑动窗口协议

流水线机制

解决停等协议性能低下的问题,允许一个接一个的发送多个包。

  • 需要更大的序列号,接收方、发送方需要更大的缓存空间

通过滑动窗口协议实现流水线机制。

使用窗口来管理发出去但是还没确认的分组

image.png

GBN(Go Back N 回到第M步)协议

发送方窗口大小>=1,接收方窗口大小=1,GBN协议采用了累计确认:只有在n到n之前的所有数据都已经被正确接收才会发送对于n的ACK。 计时器超时:GBN只会给send_base所在的分组设置定时器,当发生超时时会重传序列号大于等于n,还未接收到ACK的所有分组。 乱序到达的分组:直接丢弃(GBN接收方没有缓存),重新确认序列号最大的、按序到达的分组。

SR(Selective Repeat)协议

发送方窗口大小>=1,接收方窗口大小>=1,解决GBN的累计确认问题,缓存乱序到达的分组。 接收只需要重传没有接收到ACK的分组,需要为每个分组单独设置一个定时器。 与GBN相比多了一个接收方的滑动窗口。

image.png 发送方和接收方的窗口彼此并不同步。双方不知道对方的窗口处于什么状态。

SR滑动窗口协议双方处理过程

image.png

SR协议的问题

双方窗口尺寸大小问题

image.png

由于可用的序列号比较少,窗口尺寸比较大导致。因此序列号数量和窗口尺寸之间的关系应满足以下关系:

序列号的位数是k,发送方窗口尺寸+接收方窗口尺寸<=2^k

UDP协议(User Datagram Protocol)

UDP提供 Best effort 服务的服务(尽力而为)

  • 丢失
  • 非按序到达

UDP只做了两件事情:

  • 复用/分用:任何传输层都需要实现
  • 简单的错误校验:端到端的错误检测机制,由于在路由器链路中也可能出错所以在应用层最近的一层增加错误检测机制。

无连接

发送方和接收方不需要握手 每一个UDP段的处理独立于其他段

UDP存在的价值

  • 无需建立链接:减少延迟
  • 实现简单:无需维护链接状态
  • 头部开销少
  • 没有拥塞控制:应用可以更好的控制发送时间和速率

UDP的用途

  • 流媒体应用
  • 容忍丢失
  • 速率敏感

UDP还用于

  • DNS
  • SNMP(简单网络管理系统)

在UDP上实现可靠数据传输?

  • 在应用层增加可靠性机制
  • 应用特定的错误恢复机制

UDP数据结构

image.png

UDP校验和(checksum)

检测UDP段在传输中是否发生错误(如位翻转)

发送方:

  • 将段的内容视为16-bit整数
  • 检验和计算:将伪部首和数据部分按16位对齐相加,进位加在和的后面。将得到的值取反,得到检验和
  • 发送方将校验和放入校验和字段

接收方:

  • 计算所得到段的校验和
  • 将其与校验和字段进行比对
    • 不相等:检测出错误
    • 相等:没有检测出错误(但可能有错误)

校验和计算示例: image.png

TCP 协议

  • 点对点:一个接收方,一个发送方
  • 可靠、按序的字节流
  • 流水线机制(滑动窗口实现)
  • 接收方/发送方缓存
  • 全双工(full-duplex):同一个连接中能够传输双向数据流
  • 面向连接
    • 通信双方在发送数据之前必须建立连接。
    • 连接状态只在连接的两端中维护,在沿途节点中并不维护状态(区别于网络层)
    • TCP的连接包括:两台主机上的缓存、连接状态变量、socket等
  • 流量控制机制
  • 拥塞控制机制

TCP段结构

image.png

  • 序列号:序列号指Segment中的第一个字节的编码,在TCP连接时,双方随机选择序列号
  • ACKs:希望接收到的下一个字节的序列号。采用累计确认(类似于GBN):该序列号之前的所有字节均已被正确接收到才回复ACK
  • 接收方如何处理乱序到达?规范中没有规定,由TCP的实现者做出决策。

TCP可靠数据传输

  • 流水线机制
  • 累计确认机制
  • TCP使用单一重传定时器
  • 触发重传的事件
    • 超时
    • 收到重复ACK
  • 流量控制
  • 拥塞控制

定时器定时时长和RTT(分组往返时间)估计

RTT时间需要评估过往的RTT值和当前的RTT值,采用指数加权平均:

EstimateRTT = (1-α)*EstimateRTT + α*SampleRTT

α通常为0.125,SampleRTT为最近一次超时时长

设置定时器超时时间

EstimatedRTT + 安全边界

计算RTT的变化值: SampleRTT和EstimatedRTT的差值

DevRTT = (1-β)*DevRTT + β * |SampleRTT-EstimateRTT|

β通常为0.25

定时器超时时间设置为:EstimatedRTT + 4*DevRTT

TCP的滑动窗口实现

发送方:
  • 定时器:单独为base_send设置单个定时器,当定时器超时,重传base_send这个这个分组(TCP重传一个,GBN则是重传所有分组)
  • 快速重传:当接收方累计确认了一个分组第四次时即使定时器还没到,也立即重传该分组(相当于变相的说明该分组丢失了)

接收方:

  • ACK:接收方每次确认的需要是按序到达的n+1个分组的首字节,即按序未到达的第一个分组
  • 乱序到达的分组:接收方会一并缓存,但是ACK确认的序号是中间未到达的分组序号
  • 累计确认:当按序到达了一个分组,接收方会延迟发送ACK最多等待500ms,如果等到下一个按序分组则共同发送一个ACK

TCP重传示例

接收方:

image.png

image.png

发送方:

延迟ACK,用于累计确认ACK image.png

快速重传机制

通过发送方接收到重复的ACK,来判断分组已经丢失。具体的发送方在接收到三个重复的ACK请求就假定这个分组已经丢失,需要重传该分组。

TCP流量控制

避免发送方发送数据过多/过快接收方的缓存容纳不下直接丢弃。流量控制是一种发送方和接收方速度匹配的机制。

计算RcvWindow的大小,接收方缓存剩余可用空间 image.png

接收方在回复ACK的时候将RcvWindow的尺寸通过头部字段回传。

思考一下如果RcvWindow=0时会发生什么?

会导致发送方得知后便不再发送消息,从而导致就算接收方就算有了可用空间也无法通知接收方。

因此为了解决这个问题,尽管发送方得知接收方的RcvWindow=0也需要尝试发送一个很小的分组去试探接收方的情况。

TCP的链接管理

TCP 接收方和发送方在传输数据之前需要先建立链接

  • 初始化TCP变量
    • 序列号
    • 流量控制信息
    • ...
// Client
Socket clientSocket = new Socket('hostname','port number')
// Server
Socket connectionScoket = welcomeSocket.accept()

三次握手

image.png

Client:我要给你发送消息 Server:好的 Client:好的,我的消息是

四次握手

image.png

Client:我发完了 Server: 好的 Server: 我也发完了 Client:好的(这里Client可能会再等一等确定Server不再发消息)

通过TCP的连接建立进行网络攻击,有兴趣可以查阅相关资料。

TCP的生命周期

image.png

TCP拥塞控制

拥塞控制与流量控制机制的区别在于拥塞控制为了避免端到端之间的网络链路出现拥堵瘫痪,控制各个端系统的发送速率。

拥塞控制可以分为:

  • 端到端的拥塞控制,通过判断网络行为来判断是否发生拥塞。如:分组丢失,延迟等。(TCP使用)
  • 网络辅助的拥塞控制,路由器会向发送方显示的反馈网络的拥塞信息,简单的拥塞指示如:SNA、DECbi、TCP/IP ECN、ATM

ATM 网络辅助型拥塞控制

在ATM网络中使用的一种拥塞控制

  • 弹性服务 ABR(available bit rate)
  • RM(resource management) cells: ATM网络中将分组称为cell,在ATM网络中不仅有data cells,还有一种穿插在data cells中的RM cells,同样由发送方发送。在传输的过程中网络设备(在ATM中是交换机)会改变RM cells的位 NI bit: rate不许增长CI bit: 拥塞指示。RM cell 由接收方返回给发送方。另外Data cell 也可以设置拥塞情况

TCP的拥塞控制机制

拥塞控制的基本原理就是要控制发送速率。

拥塞窗口:Congwin,已发送未确认的窗口大小

LastByteSentLastByteAcked<=CongWinLastByteSent - LastByteAcked <= CongWin
rate=CongWin/RTTrate = CongWin/RTT

通过控制CongWin的大小来控制发送的速率

TCP 感知网络拥塞:

  • timeout
  • 3个重复ACK

TCP 合理控制发送速率

  • 加性增-乘性减:AIMD
  • 慢启动:SS
AIMD:
  • Additive Increase: 每个RTT将CongWin增大一个MSS(线性缓慢的增加CongWin大小)
  • Multiplicative Decrease: 发生loss后将CongWin减半(快速的降低发送速率,以快速缓解拥堵)

image.png

慢启动:
  • 当初始建立连接时,拥塞窗口指数性增长。
  • 当到达拥塞窗口的1/2时增长由指数性变为线性,Threshold = CongWin * (1/2)
  • 当检查到拥塞发生就将CongWin设置为初始值,同时Threshold设置为原先CongWin的一半

image.png

Reno的优化将拥塞窗口减为原来的一半

TCP的性能

image.png

TCP具有公平性吗

image.png

TCP 和 UDP 共同使用时的公平性

image.png