UDT库 https://sourceforge.net/projects/udt/?source=directory
C#包装:https://github.com/dump247/udt-net
UDT协议是什么?是一种基于UDP的数据传输协议(UDP-based Data Transfer Protocol,简称UDT)。
UDT协议的主要作用是什么?UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。
那么UDT与UDP的区别又是什么?UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。
UDT的使用场景是什么?由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
(以上问题的答案均摘自wikipedia)当然我今天也不是来当知识搬运工的,而是结合以上UDT协议的基本定义来深入到UDT协议内部去解析它。
UDT协议的主要特性有哪些?
基于UDP的应用层协议: 有基本网络知识的朋友都知道TCP和UDP的区别和使用场景,但是有没有一种协议能同时兼顾TCP协议的安全可靠和UDP协议的高效,那么UDT就是一种。
面向连接的协议:面向连接意味着两个使用协议的应用在彼此交换数据之前必须先建立一个连接,当然UDT是逻辑上存在的连接通道。这种连接的维护是基于握手、Keep-alive(保活)以及关闭连接。
可靠的协议:依靠包序号机制、接收者的ACK响应和丢包报告、ACK序号机制、重传机制(基于丢包报告和超时处理)来实现数据传输的可靠性。
双工的协议:每个UDT实例包含发送端和接收端的信息。
单播的数据流。
新的拥塞算法,并且具有可扩展的拥塞控制框架:新的拥塞控制算法不同于基于窗口的TCP拥塞控制算法(慢启动和拥塞避免),是混合的基于窗口的、基于速率的拥塞控制算法。可扩展的拥塞控制框架开源的代码和拥塞控制的C++类架构,可支持开发者派生专用的拥塞控制算法。
带宽估计:UDT使用对包(PP -- Packet pair)的机制来估计带宽值。即每16个包为一组,最后一个是对包,即发送方不用等到下一个发送周期内再发送。接收方接收到对包后对其到达时间进行记录,可结合上次记录的值计算出链路的带宽(计算的方法称为中值过滤法), 并在下次ACK中进行反馈。
ENET库
c#包装1:https://github.com/RainsSoft/enetcs
c#包装2:https://github.com/RainsSoft/ENetSharp
大家都知道UDP这个东西太不可靠了,存在着乱序,丢包,包重复等缺点,但它的速度快,包有界等优点,但在实际编程中要自己处理乱序啊之类的问题会发疯 的。也许大家说用TCP就得了,第一点TCP的速度比较慢,第二个TCP是一个数据流一样的东西,我们要传数据的话还得处理数据的分界问题,也挺麻烦的。
针对这个问题,ENET这个库实现了一个性能介于TCP与UDP之间,完成可靠(不丢包,按序),保持数据的分界的优点。编程起来也挺方便的。
下载地址:http://enet.bespin.org/SourceDistro.html
RakNet库 https://github.com/OculusVR/RakNet
c#包装:https://github.com/RainsSoft/RakNet-C-Sharp-binding-project
RakNet是一个基于UDP网络传输协议的C++网络库,允许程序员在他们自己的程序中实现高效的网络传输服务。通常情况下用于游戏,但也可以用于其它项目。
RakNet有以下特点:
l 高性能 在同一台计算机上,RakNet可以实现在两个程序之间每秒传输25,000条信息;
l 容易使用 RakNet有在线用户手册,视频教程。每一个函数和类都有详细的讲解,每一个功能都有自己的例程;
l 跨平台,当前RakNet支持Windows, Linux, Macs,可以建立在Visual Studio, GCC, Code,Blocks, DevCPP 和其它平台上。
l 在线技术支持 RakNet有一个活跃的论坛,邮件列表,你只要给他们发信,他们可以在几小时之内回复你。
l 安全的传输 RakNet在你的代码中自动使用SHA1, AES128, SYN,用RSA避免传输受到攻击
l 音频传输 用Speex编码解码,8位的音频只需要每秒500字节传输。
l 远程终端 用RakNet,你能远程管理你的程序,包括程序的设置,密码的管理和日志的管理。
l 目录服务器 目录服务器允许服务器列举他们自己需要的客户端,并与他们连接。
l Autopatcher Autopatcher系统将限制客户端传输到服务端的文件,这样是为了避免一些不合法的用户将一些不合法的文件传输到服务端。
l 对象重载系统
l 网络数据压缩 BitStream类允许压缩矢量,矩阵,四元数和在-1到1之间的实数。
l 远程功能调用
l 强健的通信层 可以保障信息按照不同的信道传输
UDT基于一种基于带宽速率控制的拥塞控制算法进行设计,主要用在小数量的bulk源共享富裕带宽的情况下,最典型的例子就是建立在光纤广域网上的网格计算,而在ISP提供带宽有限的情况下运行却显得消耗资源并性能不足。甚至可能被防火墙,或ISP服务商判断为恶意带宽使用攻击。
RakNet是为游戏应用而设计,对于实时性等游戏相关的网络需求有很好的支持,对于大批量数据传输却有点力所不及。raknet的缺点是不支持组播
源码: https://github.com/skywind3000/kcp
c#包装:https://github.com/RainsSoft/kcp-csharp
KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。 连时钟都需要外部传递进来,内部不会有任何一次系统调用。
整个协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。也许你实现了一个P2P,或者某个基于 UDP的协议,而缺乏一套完善的ARQ可靠协议实现,那么简单的拷贝这两个文件到现有项目中,稍微编写两行代码,即可使用。
KCP协议比较
如果网络从来不丢包,那么你直接用 TCP就行了,甚至直接裸UDP都没关系,但是网络因为丢包造成卡顿,特别是高峰时期丢包会上到10%的情况,移动设备上这个情况更糟糕。
我自己评测过很多,asio_kcp 的作者做过比较详细的评测,在网络变糟糕的情况下,KCP的延迟比 libenet低三倍以上:
worst network lag happen:
asio: 10:51.21
291 295 269 268 231 195 249 230 225 204
enet: 10:51.21
1563 1520 1470 1482 1438 1454 1412 1637 1588 1540
更详细的评测可以看这里:benchmark,感谢 asio_kcp 的作者 zhangyuan 详细对比了 UDT, libenet和 kcp,并给出结论如下:
其他可以左右你选择的情况:
我当年主要测试了 KCP和 TCP/UDT的比较,扫了一眼 libenet觉得协议实现中规中矩,缺乏很多现代传输协议的技术,所以并没有详细测试。而 asio-kcp的作者同时给出了KCP/enet/udt三者的详细比较,为犹豫选择的人提供了更多指引。
The bench mark is for realtime pvp game. For example, the multiplayer first person shooting game.
The requirement of realtime pvp game is packet is small and frequently.
It wants a minimal delay. And the worst delay should be not so worse.
The test client send 500 bytes in every 50 milliseconds. And the server send it back after receiving immediately.
https://github.com/RainsSoft/lidgren-network-gen3
纯C#实现的UDP开源库,可用于游戏,支持NAT,内部使用的可靠ARQ协议算法没仔细去研究,不知道WIFI以及3G/4G下的表现怎么样,暂时没有测试数据