ESC
输入关键词搜索文章
目录

实时通信(一):网络基础,延迟、抖动、丢包与拥塞控制

RTT往返延迟
Jitter到达抖动
Loss丢包
Queue排队

本篇先解决哪些词

物理层 解释比特如何穿过线缆、光纤和无线信道;TCP 解释可靠有序的字节流;UDP 解释不保证到达的数据报;RTP/RTCP 解释实时媒体如何标时间、排顺序和回传质量;FEC/NACK 解释丢包后如何提前纠错或请求重传。先理解这些,再看 WebRTC 才不会被缩写淹没。

预备章
先把“通信”这件事分层看清楚

实时通信不是一个单独协议能完成的事情。一次语音通话从麦克风到扬声器,要经过物理介质、链路接入、IP 路由、传输协议、媒体协议和应用逻辑。分层的意义是:每层只解决自己能解决的问题,上层不要把所有问题都误判成“网络不好”。

层次它负责什么实时通信里常见问题
物理层把比特变成电信号、光信号或无线电波,在网线、光纤、Wi-Fi、蜂窝网络上传播距离、信号衰减、无线干扰、弱信号、基站切换
数据链路层在同一个局域网或接入链路内传帧,处理 MAC 地址、Wi-Fi 重传、以太网帧Wi-Fi 竞争、链路层重传、局域网拥塞
网络层用 IP 地址跨网络转发包,决定从源主机到目标主机走哪条路路由绕路、跨运营商、NAT、防火墙、路径 MTU
传输层用端口把数据交给具体应用,并提供 TCP 或 UDP 这样的传输语义TCP 队头阻塞、UDP 丢包、拥塞控制、端口不可达
应用 / 媒体层定义业务协议和媒体协议,例如 HTTP、WebSocket、RTP、RTCP、WebRTC编码码率、关键帧、Jitter Buffer、NACK、FEC、A/V Sync

物理层不是“代码层”,但它会决定代码的上限

物理层 关心比特如何穿过真实世界:铜线里的电信号、光纤里的光脉冲、空气里的无线电波。它不认识 TCP、UDP 或 WebRTC,只负责尽力把 0 和 1 传过去。弱网中的信号衰减、Wi-Fi 干扰、蜂窝切换,本质上都可能先从物理层或链路层表现出来,再向上变成 RTT 抖动、丢包和码率下降。

排障顺序:先分清问题发生在哪一层。DNS 失败不是 RTP 问题,Wi-Fi 干扰不是编码器问题,TCP 队头阻塞也不是 WebRTC 自身的媒体算法问题。
第一章
实时通信的敌人不是慢,而是不确定

普通文件下载关心总耗时,实时音视频关心每一小段声音和画面能不能按时到。一个视频包晚到 500 ms,即使最终没丢,对播放器也几乎等价于丢了:它错过了播放时刻。

实时通信里的四个基础指标

Latency 是端到端延迟;RTT 是往返时间;Jitter 是包到达间隔的波动;Packet Loss 是包没有按时到达或完全丢失。RTC 系统不是追求零延迟,而是在可接受延迟内吸收抖动、恢复丢包、避免排队失控。

核心判断:实时系统最怕 bufferbloat。带宽不足会降清晰度,排队失控会让互动感直接消失。

延迟通常由传播、传输、处理和排队组成。传播延迟来自物理距离,无法用代码消除;传输延迟来自链路速率和包大小;处理延迟来自编码、解码、加密、转发;排队延迟则来自路由器、系统 socket buffer、发送队列和服务端媒体队列。实时通信优化最常见的战场就是排队延迟。

第二章
先讲清楚 TCP 和 UDP 是什么

在进入 WebRTC 之前,先要分清网络栈里的两个基础传输协议:TCPUDP。它们都工作在 IP 之上,负责把一台机器上的应用数据送到另一台机器上的应用端口;区别在于,TCP 把网络伪装成一条可靠、有序的字节流,UDP 则只提供最小的数据报投递能力。

TCP:Transmission Control Protocol

TCP 的全称是 Transmission Control Protocol,传输控制协议。它提供连接、可靠传输、有序交付、丢包重传、流量控制和拥塞控制。应用层看到的是一条连续字节流:只要连接还在,发出去的数据最终会按顺序交给对端,除非连接失败。

TCP 三次握手:为什么连接要来回三步

TCP 不是“发一个包就开始传业务数据”。它先要建立连接状态,让两端确认彼此都能收发,并同步初始序列号。这个过程就是三次握手。

步骤方向含义
1. SYN客户端 → 服务端客户端说:我要建立连接,这是我的初始序列号
2. SYN-ACK服务端 → 客户端服务端说:我收到了,也给你我的初始序列号
3. ACK客户端 → 服务端客户端说:我也收到了你的确认,连接可以开始传数据
三次握手的本质:不是形式主义,而是确认“双向通信都可达”并同步双方的序列号。少一次,服务端无法确认客户端是否真的收到自己的响应;多一次,通常又没有必要。

UDP:User Datagram Protocol

UDP 的全称是 User Datagram Protocol,用户数据报协议。它不建立连接,不保证可靠,不保证顺序,也不自动重传。应用层发出的每个数据报都相对独立:网络尽力送达,送不到就丢,先后顺序也可能变化。

问题TCP 的答案UDP 的答案
要不要先建立连接?要。通过握手建立连接状态不要。应用可以直接发数据报
丢包怎么办?传输层自动重传,直到成功或连接失败传输层不管,由应用自己决定是否补救
乱序怎么办?传输层重排,按顺序交付给应用应用自己识别乱序、重排或丢弃
会不会阻塞后续数据?会。前面的字节没补齐,后面的字节不能越过它不会天然阻塞。新包到了就可以交给应用处理
典型场景网页、文件下载、接口请求、数据库连接实时音视频、游戏状态同步、DNS、低延迟遥测

为什么媒体更偏爱 UDP

TCP 适合网页、文件、接口请求,但对实时媒体有一个根本问题:队头阻塞。只要前面的字节没补齐,后面的字节即使已经到达,也不能交给应用层。对视频来说,这可能意味着为了等一个过期包,把后面已经可播放的新画面也堵住。

UDP 把选择权交给应用层:哪些包值得等,哪些包过期就丢,哪些关键帧需要重发,码率如何降,是否打开 FEC 或 NACK。WebRTC 正是建立在这种思路上:媒体通常走 UDP/RTP,可靠性和拥塞控制由实时媒体栈自己做。

WebRTC:不是一个协议,而是一套实时媒体协议栈

WebRTC 可以理解为浏览器和客户端里的实时音视频通信能力集合。它把采集、编码、网络探测、NAT 穿透、安全传输、RTP 媒体发送、RTCP 反馈、拥塞控制和播放缓冲串起来,让两个端或多个端可以低延迟传音视频和数据。

WebRTC 在网络栈中的位置

WebRTC 的媒体面通常运行在 UDP 之上,用 RTP 承载音视频帧,用 RTCP 回传接收质量、丢包、抖动、码率估计等控制信息;同时用 DTLS/SRTP 做加密,用 ICE/STUN/TURN 解决 NAT 和连通性问题。也就是说,UDP 只负责尽力投递数据报,真正的实时媒体语义主要由 RTP/RTCP 和 WebRTC 媒体栈完成。

UDP 和 RTP 的关系:UDP 送包,RTP 说明这个包是什么

UDP 只知道“从 A 端口发一个数据报到 B 端口”,它不知道这个数据报里是音频、视频、关键帧还是普通帧。RTP 负责给实时媒体数据加上时间戳、序列号、载荷类型、同步源标识等信息,让接收端可以判断包的顺序、播放时间和属于哪一路媒体流。

协议解决的问题它不解决什么
UDP按端口发送独立数据报不保证到达、不保证顺序、不知道媒体时间
RTP描述实时媒体包的序列、时间戳、载荷类型和同步源本身不负责 NAT 穿透,也不保证一定可靠送达
RTCP反馈接收质量、丢包、抖动、RTT、关键帧请求等控制信息不直接承载主要音视频帧
WebRTC把采集、编码、RTP/RTCP、加密、拥塞控制、NAT 穿透和播放串成工程系统不是单一网络包格式

FEC 和 NACK:实时媒体怎么补救丢包

UDP 不自动重传,实时媒体就必须自己决定“丢了以后怎么办”。最常见的两种机制是 FECNACK

机制全称怎么工作适合场景代价
FECForward Error Correction,前向纠错发送端额外发送冗余校验数据;接收端即使丢了少量原始包,也可能用冗余信息恢复RTT 较高、重传来不及、音频或低延迟视频占用额外带宽,丢包过多时仍然恢复不了
NACKNegative Acknowledgement,否定确认接收端发现 RTP 序列号缺口后,通过 RTCP NACK 告诉发送端“这个包没收到”,发送端选择性重传RTT 较低、包还没过播放截止时间、视频关键数据值得补增加一次往返,晚到的重传包可能已经过期
选择原则:FEC 是“提前买保险”,NACK 是“丢了再追件”。弱网高 RTT 下更依赖 FEC;低 RTT 下 NACK 更省带宽;生产系统通常会根据媒体类型、码率、RTT、丢包率和播放缓冲动态组合。
维度TCPUDP + RTP/WebRTC
可靠性传输层保证全部送达应用层选择性恢复
顺序严格有序,可能队头阻塞可乱序到达,由 jitter buffer 重排
实时性旧数据可能阻塞新数据过期包可以丢弃
适合场景文件、网页、API音视频、游戏、实时控制
一句话区分:TCP 更像“保证每页都按顺序送到的快递”,UDP 更像“按时送达优先的现场广播”。实时音视频宁愿丢掉过期画面,也不愿为了补旧包把新画面全部堵住。
第三章
拥塞控制:不是“尽量发”,而是“别把队列打爆”

实时通信的发送端需要持续估计可用带宽。发少了,画质差;发多了,路由器和服务端队列堆积,延迟上升,最后丢包和卡顿一起出现。现代 RTC 的拥塞控制会综合丢包、延迟梯度、RTT、接收端反馈和码率变化,动态调整编码码率、分辨率、帧率和发送节奏。

graph LR
    A["发送端编码器"] --> B["RTP 包发送"]
    B --> C["网络队列 / 丢包 / 抖动"]
    C --> D["接收端统计"]
    D --> E["RTCP feedback"]
    E --> F["带宽估计 / 拥塞控制"]
    F --> A
排障时不要只看平均码率

平均码率正常但用户仍觉得卡,常见原因是 p95/p99 延迟、jitter、关键帧请求、发送队列和解码队列异常。实时通信排障要看时间序列,而不是只看单个平均值。

第四章
生产排障:先问是哪一种坏

真实线上问题通常不是“网络不好”四个字能解释。要先判断坏的是建连、上行、下行、编码、解码、渲染,还是服务端转发。网络层常用的切入口包括 RTT 是否升高、jitter 是否突刺、丢包是上行还是下行、NACK/PLI/FIR 是否频繁、发送码率是否被带宽估计压低、socket 或 pacer 队列是否堆积。

现象可能原因优先看什么
声音断续上行丢包、jitter buffer underrun、音频编码过载audio jitter、concealed samples、RTT、上行 loss
画面糊但不卡拥塞控制降码率、simulcast 订阅低层target bitrate、actual bitrate、selected spatial layer
画面卡住后恢复关键帧丢失、PLI 后等待新关键帧PLI/FIR 次数、keyframe interval、decoder dropped frames
延迟越来越大队列堆积、jitter buffer 过大、发送节奏失控pacer queue、jitter buffer delay、render delay