1、高通信 实时性要求 和 低持续性要求 的场景下
在分组交换通信当中,协议栈的成本主要表现在以下两方面:
[1] 封装带来的空间复杂度;
[2] 缓存带来的时间复杂度。
以上两者是对立影响的,如果想减少封装消耗,那么就必须缓存用户数据到一定量在一次性封装发送出去,这样每个协议包的有效载荷将达到最大化,这无疑是节省了带宽空间,带宽利用率较高,但是延时增大了。
如果想降低延时,那么就需要将用户数据立马封装发出去,这样显然会造成消耗更多的协议头等消耗,浪费带宽空间。
因此,我们进行协议选择的时候,需要重点考虑一下空间复杂度 和 时间复杂度间 的 平衡。
通信的持续性对两者的影响比较大,根据通信的持续性有两种通信类型:
[1] 短连接通信;
[2] 长连接通信。
对于短连接通信:
一方面如果业务只需要发一两个包并且对丢包有一定的容忍度,同时业务自己有简单的轮询或重复机制,那么采用 UDP 会较为好些。
在这样的场景下,如果用 TCP,仅仅握手就需要 3 个包,这样显然有点不划算,一个典型的例子是 DNS 查询。
另一方面,如果业务实时性要求非常高,并且不能忍受重传,那么首先就是 UDP 了或者只能用 UDP 了,例如 NTP 协议,重传 NTP 消息纯属添乱(为什么呢?重传一个过期的时间包过来,还不如发一个新的 UDP 包同步新的时间过来)。
如果 NTP 协议采用 TCP,撇开握手消耗较多数据包交互的问题,由于 TCP 受 Nagel 算法等影响,用户数据会在一定情况下会被内核缓存延后发送出去,这样时间同步就会出现比较大的偏差,协议将不可用。
2、多点通信的场景下
对于一些多点通信的场景,如果采用有连接的 TCP,那么就需要和多个通信节点建立其双向连接,然后有时在 NAT 环境下,两个通信节点建立其直接的 TCP 连接不是一个容易的事情,在涉及 NAT 穿越的时候,UDP 协议的无连接性使得穿透成功率更高.
(原因详见:由于 UDP 的无连接性,那么其完全可以向一个组播地址发送数据或者轮转地向多个目的地持续发送相同的数据,从而更为容易实现多点通信。)
一个典型的场景是:
多人实时音视频通信,这种场景下实时性要求比较高,可以容忍一定的丢包率。
比如:对于音频,对端连续发送 p1、p2、p3 三个包,另一端收到了 p1 和 p3,在没收到 p2 的保持 p1 的最后一个音(也是为什么有时候网络丢包就会听到嗞嗞嗞嗞嗞嗞…或者卟卟卟卟卟卟卟卟…重音的原因),等到到 p3 就接着播 p3 了,不需要也不能补帧,一补就越来越大的延时。