网络协议之: 基于 UDP 的高速数据传输协议 UDT
简介
简单就是美。在网络协议的世界中,TCP 和 UDP 是建立在 IP 协议基础上的两个非常通用的协议。我们现在经常使用的 HTTP 协议就是建立在 TCP 协议的基础上的。相当于 TCP 的稳定性来说,UDP 因为其数据传输的不可靠性,所以用在某些特定的场合,如直播、广播消息、视频音频流处理等不太需要校验数据完整性的场合。
UDP 相对 TCP 协议而言,其特点就是简洁,它删除了在 TCP 协议中为了保证消息准确性的各种限制性特征。简洁带来的好处就是快!今天给大家讲解一下,基于 UDP 的高速数据传输协议 UDT。
UDT 协议
UDP 因为其简单的特性,所以可以做到很多 TCP 做不到的事情,比如进行大数据量的快速传输。这里并不是要将 TCP 和 UDP 分个好坏高下,毕竟各个协议的适应场景不同,他们之所以流行,就是因为可以在特定的场景发挥出重要的作用。套用中国的一句谚语就是:不管白猫黑猫,能抓到老鼠的,就是好猫。
用好 UDP 协议,我们就可以快速的传递大量的数据,这个协议就是 UDT 协议。
话说,像这些基础协议都是老外发明的,而中国的互联网巨头都在抢着做平台、做流量的生意,真的是无话可说….
UDT 项目开始于 2001 年,是由 Yunhong Gu 在芝加哥伊利诺伊大学国家数据挖掘中心 (NCDM)读博士期间开发的,并在毕业之后持续的进行维护和升级改进。
UDP 的出现是因为那时候,传输更快更便宜的光纤网络出现了,代替了之前的铜缆线和双绞线,从而极大的提升了信息传输的效率。这时候大家就发现之前使用 TCP 协议来进行大数据的传输会有很大的问题。从而基于 UDP 的 UDT 协议出现了。
UDT 的第一个版本,也称为 SABUL(Simple Available Bandwidth Utility Library),UDT 通过支持批量数据传输,从而方便在私有网络中进行数据的传输。
要注意的是 UDT 的第一个版本 SABUL 使用 UDP 协议进行传输数据,同时使用单独的 TCP 协议连接传输控制消息。
UDT 的初始版本是在超高速网络(1 Gbit/s、10 Gbit/s 等)上进行开发和测试的,2003 年 10 月,NCDM 实现了从美国芝加哥到荷兰阿姆斯特丹的平均每秒 6.8G 比特的传输。在 30 分钟内的测试中,他们传输了大约 1.4TB 的数据。
从 2004 年发布的 2.0 版本开始,SABUL 改名为 UDT,UDT 的全称是 UDP-based Data Transfer Protocol,也就是基于 UDP 的数据传输协议。
为什么要改成 UDT 呢?因为在 UDT2.0 中,删除了 SABUL 中的 TCP 控制连接,并使用 UDP 来处理数据和控制信息。 另外,UDT2 还引入了一种新的拥塞控制算法,允许协议动态调整 UDT 和 TCP 流,实现 UDT 和 TCP 流的并发运行。
在 2006 年,UDT 协议升级到了 3 版本,该协议不仅是在私有网络中运行了,而是扩展到了商业互联网中。同时 UDT3 中的拥塞控制可以进行调整优化,可以在低带宽的环境中运行,并且允许用户轻松定义和安装自己的拥塞控制算法。另外,UDT3 还显着减少了系统资源(CPU 和内存)的使用。
2007 年,UDT4 版本在高并发和防火墙穿透方面进行优化和性能的提升。UDT4 允许多个 UDT 连接绑定到同一个 UDP 端口,它还支持集合连接设置,以便 UDP hole punching。
什么是 UDP hole punching 呢?
UDP hole punching 通常被用在网络地址转换 (NAT)中。用来维护穿越 NAT 的用户 UDP 数据包流。它是一种使用网络地址转换器在专用网络中的 Internet 主机之间建立双向 UDP 连接的方法。
什么是 NAT 呢?
大家都知道 IPV4 地址是有限的,很快 IPV4 地址就快用完了,那怎么解决这个问题呢?
当然,一个永久解决的办法是 IPV6,不过 IPV6 推出这么多年了,好像还没有真正的普及。
不使用 IPV6 的话还有什么解决办法呢?
这个办法就是 NAT(Network Address Translators)。
NAT 的原理是将局域网的 IP 和端口和 NAT 设备的 IP 和端口做个映射。
NAT 内部维护着一张转换表。这样就可以通过一个 NAT 的 IP 地址和不同的端口来连接众多的局域网服务器。
那么 NAT 有什么问题呢?
NAT 的问题在于,内部客户端不知道自己外网 IP 地址,只知道内网 IP 地址。
如果是在 UDP 协议中,因为 UDP 是无状态的,所以需要 NAT 来重写每个 UDP 分组中的源端口、地址,以及 IP 分组中的源 IP 地址。
如果客户端是在应用程序内部将自己的 IP 地址告诉服务器,并想跟服务器建立连接,那么肯定是建立不了的。因为找不到客户端的公网 IP。
即使找到了公网 IP,任何到达 NAT 设备外网 IP 的分组还必须有一个目标端口,而且 NAT 转换表中也要有一个条目可以将其转换为内部主机的 IP 地址和端口号。否则就可能出现下图的连接失败的问题。
怎么解决呢?
第一种方式是使用 STUN 服务器。
STUN 服务器是 IP 地址已知的服务器,客户端要通信之前,先去 STUN 服务器上面查询一下自己的外网 IP 和端口,然后再使用这个外网 IP 和端口进行通信。
但有时 UDP 包会被防火墙或者其他的应用程序所阻挡。这个时候就可以使用中继器技术 Traversal Using Relays around NAT (TURN) 。
双方都将数据发送到中继器 server,由中继器 server 来负责转发数据。注意,这里已经不是 P2P 了。
最后,我们有一个集大成者的协议叫做 ICE(Interactive Connectivity Establishment ):
它实际上就是直连,STUN 和 TURN 的综合体,能直连的时候就直连,不能直连就用 STUN,不能用 STUN 就用 TURN。
在使用 STUN 和 ICE 的过程中,我们会有一台网络主机用来建立端口映射和保持其他 UDP 端口状态,但是 UDP 的状态通常在几十秒到几分钟的短时间后过期,为了保证 NAT 中 UDP 的状态和生命周期,于是有了 UDP hole punching 的技术。通过定时传输 keep-alive 数据包,对 NAT 中的 UDP 状态进行更新。
UDT 的缺点
因为 UDT 是基于 UDP 协议的,但是 UDP 协议因为其简洁的特性,所以并不具备安全性的特征。所以基于其上的 UDT 协议因为缺乏安全特性,所以在商业环境中应用会受到一定的限制。
不过 UDT 的新版本已经在开发中,大家可以期待一下。
总结
UDT 被广泛用于高性能计算,比如光纤网络上的高速数据传输。我们后续会在 netty 中告诉大家怎么使用 UDT 协议。
本文已收录于 http://www.flydean.com/11-udt/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
版权声明: 本文为 InfoQ 作者【程序那些事】的原创文章。
原文链接:【http://xie.infoq.cn/article/43f6405adfe848061ea39d250】。文章转载请联系作者。
评论