可靠UDP传输协议总结

at 1年前  ca 网络协议  pv 521  by touch  

可靠UDP传输协议总结

TCP/IP协议栈中,TCP和UDP属于传输层,负责实现数据的传输。其中TCP是面向连接的和基于单个字节流的、保证顺序的可靠传输协议,UDP是无连接的、不可靠的、面向报文的协议。

在实际应用中,TCP由于简单可靠,被大部分应用层协议使用,特别是HTTP,所以占据了互联网流量的主要部分。由于TCP的广泛应用,并且是实现在操作系统中,在参数和算法调整上比较受限,难以进行一些激进的改进和定制。另外TCP的NAT穿越比较困难,一些P2P应用也只能使用UDP,所以就有了各种各样的可靠UDP协议。

可靠传输的原理

实现可靠传输一般有两种途径,一是基于ARQ(Automatic Repeat reQuest)的确认和重传机制,二是使用前向纠错(FEC)。

FEC是纠删码在通信中的应用,一般在链路层用的比较多,特别是无线通信中(包括WiFi,移动通信、卫星通信等)。可靠UDP传输主要还是依靠重传机制,个别协议会用FEC作为辅助手段,所以本文中主要介绍重传相关的技术。

ARQ

ARQ包括停等式、回退N帧、选择重传等机制。由于停等式的效率太低,TCP和可靠UDP协议一般使用的是基于回退N帧机制和滑动窗口协议的连续式ARQ,TCP后来也引入了SACK,以提高性能。

滑动窗口

滑动窗口是一种流量控制技术,接收方可以通过反馈来指示发送方调节数据发送的速度。TCP中使用滑动窗口协议来控制发送的数据量,达到理想的传输速度。

拥塞算法

TCP早期没有拥塞控制,直到1986年由于拥塞导致网络瘫痪,所以拥塞控制被引入到TCP中。拥塞算法主要是计算和调整接收窗口、发送窗口、拥塞窗口的大小,从而控制传输速度,既充分利用带宽,又避免网络出现拥塞。

最早的拥塞算法是Tahoe,后来的改进版有Reno、NewReno、BIC、CUBIC等。Linux在2.6.8之前使用的是Reno/NewReno,2.6.8到2.6.18之间使用BIC,2.6.19开始使用CUBIC。

拥塞算法的核心机制有:

  • 慢启动

在连接刚建立时接收窗口以指数方式增加,直到达到慢启动的阀值,或者是遇到丢包,开始进入拥塞回避阶段。

  • 拥塞回避

在此阶段会使用AIMD(Additive Increase Multiplicative Decrease)方式调整窗口大小,通过线性增加和指数衰减,逐渐逼近和收敛到一个理想值,从而达到充分利用带宽但又不引起拥塞的状态。

  • 快重传

发送方如果收到连续3次重复的ACK确认,就认为出现了丢包,而不需要等到重传计时器超时。这样可以更早的检测到丢包,提高算法效率。

  • 快恢复

Tahoe检测到丢包后,会回到初始状态,然后进入慢启动阶段,导致传输效率太低。Reno对此作了改进,在检测到丢包后,直接进入拥塞回避阶段,将窗口大小调整为原来的一半,避免了慢启动的开销。

拥塞算法分类

TCP的拥塞算法有很多种,按照拥塞检测的机制,可以分为三类:

  • 基于丢包

路由器和交换机在要转发的报文超过负载时会丢弃部分报文,所以丢包可以作为网络出现拥塞的一个标志,这也是TCP中主流的拥塞检测机制。从最早的Tahoe和改进版的Reno、NewReno、HSTCP、STCP、BIC、CUBIC等,都是基于丢包的,也是主流的拥塞检测机制。

  • 基于延时

现在的路由器和交换机的缓存比较大,对于超出负载的报文会先缓存起来,而不是立即丢弃。直到负载超过缓存大小,才会丢弃报文。所以当网络出现拥塞时,并不是马上丢包,而有报文丢失时,网络的拥塞已经比较严重。这样,前面基于丢包的拥塞检测机制就不够准确,于是,就有了基于延时的检测算法。

虽然这类算法可以更早的检测出拥塞,使得整个网络更有效率,但在跟基于丢包的算法竞争时,却由于过早的避让,导致性能较差,无法保证算法的公平性,所以影响了它们的应用。

这类的算法有Vegas和Fast TCP,其中Fast TCP是一种商业方案,有专利保护,在一些单边加速的场景中有应用。Vegas由于公平性的问题,没有被广泛使用。

Google新推出的BBR算法,虽然也可以归为基于延时类的,但跟传统算法有较大区别。传统算法通过AIMD来逼近理想传输速度,效率较低,而且受丢包和抖动的影响较大。BBR通过RTT和带宽乘积(BDP)来作为调整发送窗口的基础,避免了这些问题,从而提高性能和避免拥塞。

  • 显式拥塞通知(Explicit Congestion Notification)

通过IP头中2个bit的ECN标识和TCP头中的ECN-Echo位,可以在各节点以及中间设备之间显式的传递拥塞信号,从而达到避免拥塞的目的。不过由于一些终端和中间设备(路由器、交换机、网关等)并不支持ECN,导致ECN并没有广泛应用。

可靠UDP协议

UDT(UDP-based Data Transfer Protocol)

UDT的主要目的是支持高速广域网上的海量数据传输,所以除了在UDP之上实现类似TCP的协议和算法之外,UDT还对TCP的拥塞算法做了一些细节上的调整,包括Negative-ACK(NAK)、ACK to ACK(ACK2)、基于对数的动态AIMD等。不过UDT的重传效率较低,无效报文,实际效果并不理想。

KCP

KCP是一个很简单的ARQ的实现,包括选择重传和快重传等机制,对上层提供一个可靠的字节流。应用层可以使用多流复用的框架来实现对多个流的支持。另外,KCP增加了可配置启用的加密和FEC选项,FEC用的是Reed-Solomon纠删码,例如可以配置发送10%的冗余数据,来减少丢包时需要的重传,从而降低数据传输的延时。

QUIC

QUIC是Google实现的一种可靠UDP传输协议,并且已经被选择作为HTTP/3的基础。它的特点有:

  • 内建安全性,集成TLS

  • 连接建立过程和TLS协商过程合并,减少往返请求次数,提高连接速度

  • 集成多种拥塞算法,包括最新的BBR

  • 多流支持,每个流有独立的拥塞控制,避免单个流中的丢包阻塞其它所有流(Head-of-line Blocking问题),更好的支持类似HTTP/2中的乱序请求

  • 连接迁移:QUIC可以通过连接ID来唯一标识一个连接,当用户在有线、无线、移动网络之间切换时,可以保持上层连接的有效性,不需要再进行重连。

另外,早期的QUIC还使用了一种基于异或的FEC算法,不过在新版本中已经去掉。

uTP

uTP是BitTorrent中新增加的一种UDP传输协议,主要特点是使用了LEDBAT(Low Extra Delay Background Transport)拥塞算法。这种算法基于延时来检测网络拥塞,可以更早的探测到拥塞和更早的以及更大幅度的进行避让,从而避免影响用户上网操作的进行,保持后台下载跟前台操作的和平共处。

FASP(Aspera)

FASP是Aspera公司(已被IBM收购)的私有UDP解决方案,提供加密的可靠传输,拥塞算法估计是类似BBR,直接使用RTT和带宽来作为调节速度的参考。但FASP主要用于高速的文件传输,所以不需要保证报文的顺序,避免乱序重组时占用的内存开销,而且也避免了因为内存有限而丢弃的部分乱序报文,从而减少不必要的重传,提高传输速度。也就是说,完全避免了Head-of-line Blocking问题。

SCTP(Stream Control Transmission Protocol,流控制传输协议)

准确的说,SCTP不是一种可靠UDP协议,而是一种跟TCP/UDP平级的传输层协议,是IETF在2000年指定的标准协议。目前Linux和部分UNIX已经集成,Windows和Mac需要使用第三方包来实现。SCTP最初主要用于电信系统,此外,WebRTC中的DataChannel也用到这个协议。它的特点有:

  • 跟TCP一样面向连接,提供可靠传输

  • 跟UDP一样面向消息

  • 多流支持

  • 每个流可以配置成接受有序或无序的消息

  • Multi-Homing:可以配置多个地址,利用多条网络传输通道

  • 更好的安全性:要求四次握手,避免TCP的SYN Flooding攻击


版权声明

本文仅代表作者观点,不代表码农殇立场。
本文系作者授权码农殇发表,未经许可,不得转载。

 

扫一扫在手机阅读、分享本文

已有0条评论