udp因无连接特性成为音视频实时分发首选,依赖datagramsocket管理端点、datagrampacket封装rtp报文(含序列号、时间戳),结合单播/组播拓扑、合理缓冲区与线程模型实现低延迟高效传输。

UDP无连接通信本身不提供可靠性保障,但正因如此,它成为音视频实时分发的首选底层协议。关键不在“避免丢包”,而在“控制丢包影响”——用 DatagramSocket 管理端点,用 DatagramPacket 封装带上下文的报文,再配合轻量级结构(如RTP头)实现可解析、可同步、可丢弃的高效分发。
明确角色分工:Socket只管收发,Packet负责携带元信息
DatagramSocket 不维护连接状态,也不区分客户端/服务器。它只是本地网络端点的抽象:
- 接收端用 DatagramSocket(int port) 绑定固定端口,确保音视频流能被稳定监听;
- 发送端通常用无参构造 DatagramSocket(),由系统分配临时端口,避免端口冲突;
- 所有目标地址、端口、数据内容、甚至缓冲区长度,都必须封装进 DatagramPacket 实例中;
- 一个 DatagramPacket 对象既可用于接收(预先分配 byte[] 缓冲区),也可用于发送(含目的地址+端口+有效载荷)。
音视频报文必须自带序列号与时间戳(RTP 是事实标准)
纯 UDP 报文没有顺序和时序信息,直接发原始音频帧或 H.264 NALU 会导致播放卡顿、音画不同步。实际工程中几乎都叠加 RTP 封装:
- RTP 头(12字节起)包含 sequence number(检测丢包)、timestamp(驱动解码时钟)、ssrc(标识媒体流);
- 把音频采样或视频帧数据追加在 RTP 头之后,整体作为 DatagramPacket 的 payload;
- 接收端从 packet.getData() 提取完整字节数组,先解析 RTP 头,再决定是否丢弃、缓存或送入解码器;
- 例如:sequence=1001 的包没收到,后续收到 1002,就可触发“跳过一帧”逻辑,而非阻塞等待重传。
局域网内优先用单播,跨网段或一对多场景选组播(MulticastSocket)
音视频分发效率取决于拓扑适配:
- 点对点预览、远程控制等场景,用常规 DatagramSocket + 单播(指定 IP+端口)最简单稳定;
- 教室广播、监控大屏轮播等一对多场景,改用 MulticastSocket 并加入组播地址(如 239.0.0.1),可大幅降低源端带宽压力;
- 注意:组播需网络设备支持 IGMP,且接收端必须显式调用 joinGroup(InetAddress group) 才能收到数据;
- Android 或受限网络环境可能默认禁用组播,需检查系统权限(如
android.permission.CHANGE_WIFI_MULTICAST_STATE)。
缓冲区大小与线程模型直接影响吞吐与实时性
音视频对延迟敏感,收发不能阻塞主线程,也不能因缓冲区太小导致频繁截断:
- 接收缓冲区建议 ≥ 65536 字节(64KB),足以容纳一整帧高清视频(含 RTP+UDP+IP 头);
- 发送端避免高频小包,可将多个音频帧打包进一个 packet(需接收端支持解析),减少 UDP 头开销;
- 收发务必放在独立线程(如 HandlerThread 或 ExecutorService),并设置合理超时(socket.setSoTimeout(50) 防死锁);
- 频繁创建/关闭 DatagramSocket 开销大,应复用实例,用完仅 close(),不要反复 new。











