信令链路与媒体链路的基本概念
SIP通信中有两种核心通信路径,各自承担不同职责:
信令链路:
- 作用:传输呼叫控制指令,建立/终止通话,协商通话参数
- 协议:SIP协议(端口5060/5061)
- 关键消息:INVITE(呼叫请求)、BYE(挂断)、ACK(确认)
- 实际应用:用于拨号、挂机、呼叫转移等控制操作
媒体链路:
- 作用:传输实际的通话内容(语音/视频数据)
- 协议:RTP协议(动态高位端口)
- 特点:直接在通话双方之间建立,追求低延迟
- 实际应用:承载通话声音、视频画面、按键音等实际内容
媒体链路如何建立?
媒体链路通过信令链路中的SDP(会话描述协议)协商建立,主要过程:
- 呼叫方发送INVITE:包含SDP信息,说明”我能用哪些编解码器”和”我在哪个IP和端口接收媒体”
- 被叫方回复200 OK:包含SDP信息,说明”我选择用哪个编解码器”和”我在哪个IP和端口接收媒体”
- 双方根据对方的IP和端口:开始发送RTP媒体包
关键SDP字段(必须掌握)
| 字段 | 作用 | 示例 |
|---|---|---|
| c= | 指定媒体目标IP(告诉被叫要把媒体流发到哪个IP上) | c=IN IP4 192.168.1.100 |
| m= | 指定端口和编解码器 | m=audio 49172 RTP/AVP 0 8 |
| a=rtpmap | 定义编解码器详情 | a=rtpmap:0 PCMU/8000 |
| a=sendrecv/sendonly/recvonly | 控制媒体方向 | a=sendrecv |
媒体发送规则(常见错误根源)
被叫收到INVITE后,会从SDP中提取以下信息来决定如何发送媒体:
- 发送目标:对方SDP的c=字段(IP地址)和m=字段(端口号)
- 使用编解码:对方支持且自己也支持的编解码器中选择优先级最高的
- 媒体方向:根据对方指定的a=sendrecv(双向)/sendonly(单发)/recvonly(单收)属性
实用提示:单向语音问题通常是由c=字段或m=字段配置错误,或NAT设置不当导致,后面会单独放一篇文章讲解
SDP示例(实际使用参考)
// 呼叫方SDP
v=0
o=alice 2890844526 2890844526 IN IP4 192.0.2.1
s=
c=IN IP4 192.0.2.1 // 媒体接收IP
t=0 0
m=audio 49172 RTP/AVP 0 8 97 // 端口号和支持的编解码器
a=rtpmap:0 PCMU/8000 // G.711μ编解码器
a=rtpmap:8 PCMA/8000 // G.711a编解码器
a=rtpmap:97 iLBC/8000 // iLBC编解码器
a=sendrecv // 双向媒体
// 被叫方SDP
v=0
o=bob 2890844527 2890844527 IN IP4 192.0.2.2
s=
c=IN IP4 192.0.2.2 // 媒体接收IP
t=0 0
m=audio 48917 RTP/AVP 0 // 端口号和选择的编解码器
a=rtpmap:0 PCMU/8000 // 选择G.711μ编解码器
a=sendrecv // 双向媒体
根据上面的SDP:
- 呼叫方将媒体发送到:192.0.2.2:48917
- 被叫方将媒体发送到:192.0.2.1:49172
- 双方使用G.711μ(PCMU)编解码器
信令链路与媒体链路的关系
基础关系:
- 信令链路用于控制,媒体链路用于传输内容
- 信令链路协商媒体链路的参数
- 媒体链路直接连接通话双方
常见应用场景:
-
呼叫开合控制
- 开呼叫:正常双向媒体传输 (
a=sendrecv) - 合呼叫:保持通话,暂停媒体传输 (
a=sendonly/a=inactive) - 应用:呼叫保持、咨询转接、会议静音
- 开呼叫:正常双向媒体传输 (
-
媒体转发
- 原理:媒体不直接在双方之间传输,而是通过中间服务器
- 优势:解决NAT问题、实现录音、确保QoS
- 缺点:增加延迟(5-20ms)、占用服务器带宽
-
NAT穿越
- 挑战:私网用户无法直接建立媒体链路
- 解决方案:ICE/STUN/TURN协议辅助建立连接
- 操作:通过信令链路交换NAT穿越信息
实用示例
标准通话流程
呼叫方 代理服务器 被叫方
| | |
|---(1) INVITE SDP1------>| | 信令链路
| |---(2) INVITE SDP1------>| 上的消息
| | |
| |<---(3) 180 Ringing------|
|<---(4) 180 Ringing------| |
| | |
| |<---(5) 200 OK SDP2------|
|<---(6) 200 OK SDP2------| |
| | |
|---(7) ACK-------------->| |
| |---(8) ACK-------------->|
| | |
|<==================(9) RTP媒体流===================>| 媒体链路
| | | 上的数据
|---(10) BYE------------->| |
| |---(11) BYE------------->| 信令链路
| | | 上的消息
| |<---(12) 200 OK----------|
|<---(13) 200 OK----------| |
呼叫保持示例
保持呼叫时,呼叫方发送包含以下属性的re-INVITE:
// 保持呼叫的SDP
c=IN IP4 192.0.2.1
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=sendonly // 关键:只发送不接收
被叫方应回复:
// 回应保持呼叫的SDP
c=IN IP4 192.0.2.2
m=audio 48917 RTP/AVP 0
a=rtpmap:0 PCMU/8000
a=recvonly // 关键:只接收不发送
媒体转发示例
呼叫方 代理服务器 被叫方
| | |
|---(1) INVITE SDP1------>| | 信令链路
| |---(2) INVITE SDP1------>| 上的消息
| | |
| |<---(3) 180 Ringing------|
|<---(4) 180 Ringing------| |
| | |
| |<---(5) 200 OK SDP2------|
|<---(6) 200 OK SDP2------| |
| | |
|---(7) ACK-------------->| |
| |---(8) ACK-------------->|
| | |
|=====RTP流==============>|=====RTP流==============>| 媒体链路
|<====RTP流===============|<====RTP流===============| 上的消息
|---(10) BYE------------->| |
| |---(11) BYE------------->| 信令链路
| | | 上的消息
| |<---(12) 200 OK----------|
|<---(13) 200 OK----------| |
媒体路径:呼叫方 <-> 媒体服务器 <-> 被叫方(而非直接连接)
常见问题与解决方法
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 单向音频 | • SDP中c=或m=字段错误 | |
• NAT配置不当 • 防火墙阻断 |
• 检查SDP中的IP和端口 • 配置NAT穿越 • 开放相应UDP端口 |
|
| 无音频 | • 编解码器不匹配 | |
• 媒体包路由问题 • RTP端口被占用 |
• 确保双方有共同编解码器 • 检查网络路由 • 更换RTP端口 |
|
| 通话延迟 | • 网络延迟高 | |
• 媒体转发过多 • 缓冲设置不当 |
• 优化网络 • 减少媒体转发节点 • 调整抖动缓冲区 |
总结
- 信令链路负责通话控制,使用SIP协议(端口5060/5061)
- 媒体链路负责传输实际内容,使用RTP协议(动态端口)
- 媒体建立依赖SDP协商,关键字段:
- c=(目标IP)
- m=(端口和编解码器)
- a=sendrecv/sendonly/recvonly(媒体方向)
- 应用场景:
- 呼叫开合通过改变媒体方向属性实现
- 媒体转发用于解决NAT问题和实现录音等功能
- NAT穿越需要特殊协议辅助媒体链路建立