UDP 是一个简单常用的协议,经常用于引导其他传输协议。事实上,UDP 的特色在于它所省略的那些功能:连接状态、握手、重发、重组、重排、拥塞控制、拥塞预防、流量控制,甚至可选的错误检测,统统没有。这个面向消息的最简单的传输层在提供灵活性的同时,也给实现者带来了麻烦。你的应用程序很可能需要从头实现上述几个或者大部分功能,而且每项功能都必须保证与网络中的其他主机和协议和谐共存。
与内置流量和拥塞控制以及拥塞预防的 TCP 不同,UDP 应用程序必须自己实现这些机制。拥塞处理做得不到位的 UDP 应用程序很容易堵塞网络,造成网络性能下降,严重时还会导致网络拥塞崩溃。如果你想在自己的应用程序中使用 UDP,务必要认真研究和学习当下的最佳实践和建议。RFC 5405 就是这么一份文档,它对设计单播 UDP 应用程序给出了很多设计建议,简述如下:
- 应用程序必须容忍各种因特网路径条件;
- 应用程序应该控制传输速度;
- 应用程序应该对所有流量进行拥塞控制;
- 应用程序应该使用与 TCP 相近的带宽;
- 应用程序应该准备基于丢包的重发计数器;
- 应用程序应该不发送大于路径 MTU 的数据报;
- 应用程序应该处理数据报丢失、重复和重排;
- 应用程序应该足够稳定以支持 2 分钟以上的交付延迟;
- 应用程序应该支持 IPv4 UDP 校验和,必须支持 IPv6 校验和;
- 应用程序可以在需要时使用 keep-alive(最小间隔 15 秒)。
设计新传输协议必须经过周密的考虑、规划和研究,否则就是不负责任。要尽可能利用已有的库或框架,这个库或框架应该考虑了 NAT 穿透,而且能够与其他并发的网络流量和谐共存。