4、网络传输基础:TCP/IP协议栈回顾、UDP与TCP的选择、RTP/RTCP协议族、RTSP协议概述、SDP协议

好,我们正式开始网络流传输的底层部分。

说实话,很多做流媒体开发的同学,一开始就扎进GStreamer的API里,结果遇到卡顿、花屏、延迟高,完全摸不着头脑。我当年也踩过这个坑。后来发现,90%的问题都出在网络传输上,而不是编解码器。

所以这一章,咱们把网络传输的基础打牢。你想想看,如果连TCP和UDP都选不对,后面的RTP、RTSP学得再熟也没用。

4.1 TCP/IP协议栈回顾

先快速过一遍TCP/IP协议栈。这东西大学课本里都有,但咱们从流媒体的角度重新审视它。

协议栈分四层:

  • 应用层:HTTP、RTSP、SIP、RTP(没错,RTP虽然跑在传输层之上,但通常被归类为应用层协议)
  • 传输层:TCP、UDP。这是咱们今天讨论的重点。
  • 网络层:IP。负责寻址和路由。
  • 链路层:以太网、Wi-Fi。负责物理传输。

做流媒体时,我们最关心的就是传输层。为什么?因为流媒体的实时性、可靠性、带宽利用率,全在这里博弈。

核心观点:流媒体传输的本质,就是在不可靠的IP网络上,用合适的传输层协议,把音视频数据以可接受的延迟和丢包率送达对端。

4.2 UDP与TCP的选择

这是每个流媒体工程师都要面对的灵魂拷问:用TCP还是UDP?

我个人习惯,先看场景:

  • 直播、实时通话:首选UDP。延迟低,没有重传导致的队头阻塞。
  • 点播、文件下载:首选TCP。可靠性优先,延迟可以容忍。
  • 弱网环境:UDP + FEC(前向纠错)或ARQ(自动重传请求)。

为什么会这样?我举个例子。

TCP为了保证数据完整,会做重传。假设你发送了10个包,第3个丢了,TCP会等第3个包重传成功,才把后面的包交给应用层。这在流媒体里是灾难——你想想看,视频都播到第5秒了,突然卡住等第3秒的数据重传?

UDP就不一样。丢了就丢了,应用层自己决定要不要重传。RTP协议里有个机制叫RTCP NACK,就是专门干这个的。

避坑指南:我曾经在一个项目中,为了省事直接用TCP传输实时视频流。结果在Wi-Fi环境下,延迟从200ms飙升到3秒。后来换成UDP + FEC,延迟降到500ms以内,虽然偶尔有马赛克,但用户体验反而更好。

当然,UDP也有缺点。它不保证顺序,不保证不重复,甚至不保证送达。所以我们需要在UDP之上加一层协议——RTP。

4.3 RTP/RTCP协议族

RTP(Real-time Transport Protocol)是流媒体的核心。它不是传输层协议,而是应用层协议,跑在UDP之上。

RTP干三件事:

  • 给每个数据包打上时间戳(用于播放同步)
  • 给每个数据包分配序列号(用于检测丢包和排序)
  • 标识负载类型(H.264、AAC、Opus等)

RTCP(RTP Control Protocol)是RTP的孪生兄弟。它不传音视频数据,只传控制信息。

RTCP的主要功能:

  • 统计丢包率、延迟抖动
  • 提供NACK请求(告诉发送方:我丢了哪些包,请重传)
  • 提供SR/RR报告(发送方报告/接收方报告)

我习惯把RTP/RTCP比作快递员和客服的关系。RTP是快递员,只管送货;RTCP是客服,告诉你哪个包裹丢了、送得慢不慢。

关键点:RTP的序列号和时间戳是流媒体同步的基石。我在调试音画不同步问题时,第一件事就是抓包看RTP时间戳是否连续。

4.4 RTSP协议概述

RTSP(Real Time Streaming Protocol)是流媒体的遥控器。它不传数据,只传控制命令。

RTSP的命令和HTTP很像:

  • DESCRIBE:获取媒体描述(SDP)
  • SETUP:建立传输通道
  • PLAY:开始播放
  • PAUSE:暂停
  • TEARDOWN:结束会话

RTSP的典型工作流程:

客户端 → DESCRIBE → 服务器
服务器 → 200 OK + SDP → 客户端
客户端 → SETUP → 服务器
服务器 → 200 OK + 传输参数 → 客户端
客户端 → PLAY → 服务器
服务器 → 200 OK → 开始发送RTP流
...
客户端 → TEARDOWN → 服务器

嗯,这里要注意:RTSP本身不加密。如果要做安全传输,需要用RTSP over TLS(即RTSPS)。

警告:RTSP的SETUP阶段会协商传输模式。常见的模式有UDP单播、UDP组播、TCP隧道。我建议优先用UDP单播,因为TCP隧道会引入额外的延迟和队头阻塞。

4.5 SDP协议

SDP(Session Description Protocol)是媒体会话的说明书。它用文本格式描述媒体流的参数。

一个典型的SDP内容:

v=0
o=- 123456 7890 IN IP4 192.168.1.100
s=My Stream
c=IN IP4 192.168.1.100
t=0 0
m=video 5004 RTP/AVP 96
a=rtpmap:96 H264/90000
a=framerate:30
m=audio 5006 RTP/AVP 97
a=rtpmap:97 OPUS/48000/2

SDP的关键字段:

  • v=:协议版本
  • o=:会话发起者信息
  • s=:会话名称
  • c=:连接信息(IP地址)
  • t=:会话有效时间
  • m=:媒体描述(类型、端口、传输协议、格式)
  • a=:属性行(编码参数、采样率等)

我个人觉得,SDP是流媒体调试中最容易被忽略的环节。很多兼容性问题,比如客户端收不到视频、音频解码失败,最后查下来都是SDP里的rtpmap写错了。

经验之谈:我曾经遇到一个摄像头,SDP里写的编码是H264,但实际发送的是H265。客户端按H264解码,全是绿屏。后来抓包一看,payload type对不上。从那以后,我每次对接新设备,第一件事就是抓SDP和RTP包对比。

小结

这一章的内容,说白了就是流媒体传输的「地基」。

  • TCP适合可靠传输,但延迟高;UDP适合实时传输,但需要自己处理丢包。
  • RTP负责传音视频数据,RTCP负责传控制信息。
  • RTSP是遥控器,SDP是说明书。

下一章,我们会把这些协议串起来,用GStreamer实现一个完整的RTSP推流和拉流示例。到时候你会发现,理解了底层协议,写代码就像搭积木一样简单。