UDP头部结构UDP是面向数据报的简单传输层协议,不需要建立服务器与客户端的连接就能传输数据报,数据报是指从发送方到接收方的一个信息单元。正因为不需要建立连接所以它不能及时的返回传输状态,也不能确定数据是否到达发送方。
TCP头部结构TCP是面向连接的协议,因此数据传输之前必须先建立连接,通过连接来传输数据,当数据传输完成后断开连接,因此TCP相比UDP可以保证数据的可靠稳定。
概述UDP不属于连接协议,具有资源消耗少,处理速度快的优点,所以通常音频,视频和普通数据在传送时,使用UDP较多,因为即使丢失少量的包,也不会对接受结果产生较大的影响。 传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。 最简单的方式是在应用层模仿传输层TCP的可靠性传输。下面不考虑拥塞处理,可靠UDP的简单设计。
详细说明:送端发送数据时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。发送端收到了ack包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据。 目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。 开源程序1、RUDP(Reliable User Datagram Protocol) RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。 2、RTP(Real Time Protocol) RTP为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。 应用程序通常在 UDP 上运行 RTP 以便使用其多路结点和校验服务;这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用。如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。 RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。 3、UDT(UDP-based Data Transfer Protocol) 基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。 顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。 可靠UDP传输协议总结TCP/IP协议栈中,TCP和UDP属于传输层,负责实现数据的传输。其中TCP是面向连接的和基于单个字节流的、保证顺序的可靠传输协议,UDP是无连接的、不可靠的、面向报文的协议。 在实际应用中,TCP由于简单可靠,被大部分应用层协议使用,特别是HTTP,所以占据了互联网流量的主要部分。由于TCP的广泛应用,并且是实现在操作系统中,在参数和算法调整上比较受限,难以进行一些激进的改进和定制。另外TCP的NAT穿越比较困难,一些P2P应用也只能使用UDP,所以就有了各种各样的可靠UDP协议。 可靠传输的原理实现可靠传输一般有两种途径,一是基于ARQ(Automatic Repeat reQuest)的确认和重传机制,二是使用前向纠错(FEC)。 FEC是纠删码在通信中的应用,一般在链路层用的比较多,特别是无线通信中(包括WiFi,移动通信、卫星通信等)。可靠UDP传输主要还是依靠重传机制,个别协议会用FEC作为辅助手段,所以本文中主要介绍重传相关的技术。 ARQARQ包括停等式、回退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)来作为调整发送窗口的基础,避免了这些问题,从而提高性能和避免拥塞。
通过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的重传效率较低,无效报文,实际效果并不理想。 KCPKCP是一个很简单的ARQ的实现,包括选择重传和快重传等机制,对上层提供一个可靠的字节流。应用层可以使用多流复用的框架来实现对多个流的支持。另外,KCP增加了可配置启用的加密和FEC选项,FEC用的是Reed-Solomon纠删码,例如可以配置发送10%的冗余数据,来减少丢包时需要的重传,从而降低数据传输的延时。 QUICQUIC是Google实现的一种可靠UDP传输协议,并且已经被选择作为HTTP/3的基础。它的特点有:
另外,早期的QUIC还使用了一种基于异或的FEC算法,不过在新版本中已经去掉。 uTPuTP是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也用到这个协议。它的特点有:
|
|