大家好,我是bug菌,又见面了~

最近在做设计评审时,下面工程师在对用UDP和TCP中展开了激烈的讨论,而一个同事发表了这样的观点:"能用TCP绝不用UDP,UDP实在是太不靠谱了~"

说实在的我也很理解,但是对于这样的言论也容易误导人,导致很多初学者在尝试使用UDP设计的时候,只要出现一些埋得比较深的问题就会一棍子把UDP给拍死,这是我觉得不应该的。

其实UDP并没有那么不靠谱。


1、UDP数据包



首先我们看看UDP的数据包格式,数据内容本身的正确性是由UDP的**校验和(Checksum)**机制保证的:如果数据包在传输中发生比特错误(如电磁干扰),接收端会直接丢弃该包,不会将错误数据传递给应用层

然而UDP的“不可靠”主要是如下三点:


不保证数据包到达(可能丢包)

不保证顺序性(可能乱序)

不主动控制发送速率(可能拥塞丢包)


所以有些数据错乱问题的过,真不该让UDP来背,往往有时候就是自己设计的应用层逻辑设计不当

比如下面常见的一些场景:


场景1:乱序未处理

• 问题:接收端先收到后发送的包(如视频流的第2帧早于第1帧到达)。

• 根因:应用层未实现乱序重组逻辑,直接按接收顺序处理数据。

• 改进:在数据包头部添加序列号(Sequence Number),由应用层缓存并排序。


场景2:分包/合包逻辑缺失

• 问题:发送端传输了超过MTU的大数据包,IP层自动分片,但接收端未正确处理。

• 根因:应用层未实现手动分包/合包逻辑,依赖IP分片(可靠性差)。

• 改进:在应用层主动将大数据拆分为≤1472字节的块,并为每个块添加序号和偏移量。


场景3:未区分丢包与延迟

• 问题:误将延迟较高的包视为丢失,导致逻辑错误。

• 根因:未设置合理的超时重传机制

• 改进:为关键数据添加ACK确认与重传,非关键数据允许丢弃(如实时音视频)。


2、丢包原因


其实UDP的丢包主要还是与网络环境有关,

网络拥塞:路由器缓冲区溢出时,UDP包被优先丢弃(TCP会主动降速,UDP不会)。

链路质量差:无线网络(如Wi-Fi、4G)易受干扰,物理层丢包率上升。

IP分片丢失:若数据包超过MTU被分片,任一碎片丢失会导致整个UDP包不可用。

虽然会丢包,但丢包 ≠ 数据错乱, 丢包只会导致部分数据缺失(如视频卡顿、语音中断),不会破坏已接收数据的正确性,数据内容错误,已被UDP校验和过滤。


3、可靠的UDP协议设计


从前面UDP的结构大家就知道,其实它挺简洁的,UDP既然不解决这些问题,那就应用层去弥补,说实在有更多的灵活度。

UDP应用层需解决乱序、完整性、丢包三个问题就本上就比较靠谱了。

比如传输协议中增加一些字段:

| 序列号 (4B) | 时间戳 (4B) | 载荷长度 (2B) | 载荷数据 (N B) |

为了处理乱序、重复、丢包检测等问题。

对于一些关键数据添加ACK确认与重传,一些实时数据丢包了也没关系,就不需要应答了~

最好是避免IP分片,控制数据包大小≤1472字节(假设MTU=1500),大数据传输时,主动在应用层分包并添加序号。

如果你加快异常时的收发效率,可以采用前向纠错(FEC),通过发送冗余数据包,允许接收端通过算法恢复部分丢失数据(如RTP协议中的FEC机制)。

硬创社

还没有评论,抢个沙发!