1. 概述
SIP(Session Initiation Protocol)呼叫流程是VoIP通信的核心机制。本文将深入分析SIP信令在呼叫建立、维持和终止过程中的详细工作流程,帮助读者理解SIP协议的实际运作机制。
2. SIP呼叫流程基础概念
2.1 参与实体
- UAC (User Agent Client):发起请求的客户端(主叫方)
- UAS (User Agent Server):响应请求的服务端(被叫方)
- Proxy Server:代理服务器,负责路由SIP消息
- Registrar Server:注册服务器,维护用户位置信息
2.2 主要SIP方法
- INVITE:发起会话请求
- ACK:确认最终响应
- BYE:终止会话
- CANCEL:取消进行中的请求
- REGISTER:用户注册
2.3 SIP响应码分类
- 1xx:临时响应(会话进行中)
- 2xx:成功响应(请求被接受)
- 3xx-6xx:各种错误或重定向响应
3. 完整SIP呼叫流程分析
3.1 SIP呼叫与注册的关系
在深入分析SIP呼叫流程前,需要明确一个重要概念:SIP中的注册和呼叫是两个独立的过程。
注册(REGISTER)的目的:
- 在注册服务器上建立SIP URI(如sip:alice@example.com)与物理位置(如IP地址和端口)之间的映射
- 使用户能够接收来电,让系统知道”我在这里,请将我的呼叫发送到这个位置”
- 一般需要定期刷新,以保持位置信息的更新
呼叫(INVITE)的独立性:
- 发起呼叫并不一定需要先注册
- 代理服务器可以使用多种方式路由SIP请求,包括但不限于:
- 查询注册数据库(如果用户已注册)
- 使用DNS SRV记录解析
- 根据静态路由表转发
- 基于对URI的解析进行路由决策
什么情况下需要注册?
- 当用户需要接收来电时,必须注册
- 在移动环境中,IP地址可能会变化,注册允许用户更新其可达性
- 当使用多个设备时,可以通过注册使所有设备同时接收呼叫
什么情况下不需要注册?
- 仅发起呼叫的用户不需要注册
- 使用静态IP和固定路由配置的服务器之间的呼叫
- 对基于URI特定域的路由方案,如直接IP寻址(sip:user@192.168.1.1)
在本文中,我们将分别讨论注册流程和呼叫流程,以便更清晰地理解这两个过程。
3.2 网络拓扑示例
Alice (UAC) → Proxy Server → Bob (UAS)
192.168.1.100 192.168.1.1 192.168.1.200
3.2 SIP呼叫信令时序图
3.2.1 文本形式的信令流程图
Alice Proxy Server Bob
| | |
|---[1]INVITE---------->| | ← 发起呼叫
|<--[2]100 Trying-------|---[3]INVITE---------->| ← 转发呼叫请求
| |<--[4]100 Trying-------| ← 处理中响应
|<--[6]180 Ringing------|<--[5]180 Ringing------| ← 振铃响应
|<--[8]200 OK-----------|<--[7]200 OK-----------| ← 接听响应
|---[9]ACK------------->| | ← 确认接听
| |---[10]ACK------------>| ← 转发确认
| | |
|<============== RTP Media Stream =============>| ← 媒体流传输
| | |
|---[11]BYE------------>| | ← 挂断请求
| |---[12]BYE------------>| ← 转发挂断
|<--[14]200 OK----------|<--[13]200 OK----------| ← 挂断确认
注意:上述流程中没有包含注册步骤。在实际应用中,SIP呼叫和注册是两个独立的过程,并非所有呼叫都需要先进行注册。代理服务器可以基于其他路由策略(如DNS查询、静态路由表等)转发SIP请求,而不仅仅依赖于注册信息。
3.2.2 简化流程图(核心步骤)
发起呼叫 → 查找用户 → 建立连接 → 媒体传输 → 结束通话
↓ ↓ ↓ ↓ ↓
INVITE → 180 Ringing → 200 OK → RTP Stream → BYE
↓ ↓ ↓
路由转发 ACK确认 200 OK
3.3 SIP注册流程
在讨论具体呼叫流程前,我们先了解一下SIP注册过程,这对于某些类型的呼叫是必要的预备步骤。
用户代理(UA) 注册服务器
| |
|---REGISTER---------->| ← 请求注册
|<-----200 OK----------| ← 注册成功
3.3.1 注册过程详解
步骤1: Alice注册到服务器
REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-reg123
From: <sip:alice@example.com>;tag=alice123
To: <sip:alice@example.com>
Call-ID: reg-call-id-alice@192.168.1.100
CSeq: 1 REGISTER
Contact: <sip:alice@192.168.1.100:5060>
Expires: 3600
Content-Length: 0
步骤2: 服务器响应注册成功
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-reg123
From: <sip:alice@example.com>;tag=alice123
To: <sip:alice@example.com>;tag=server456
Call-ID: reg-call-id-alice@192.168.1.100
CSeq: 1 REGISTER
Contact: <sip:alice@192.168.1.100:5060>;expires=3600
Content-Length: 0
注册流程的关键点:
- 目的:将SIP URI(如sip:alice@example.com)与实际联系地址(如192.168.1.100:5060)关联
- 有效期:注册信息通常有时效性(例如3600秒),需要定期刷新
- 可选性:注册对于呼叫不是必须的,代理服务器可以使用其他方式路由SIP消息
- 应用场景:主要用于用户需要接收来电的情况,发起呼叫不一定需要先注册
3.4 详细呼叫流程
3.4 详细呼叫流程
3.4.1 阶段1:呼叫建立(INVITE Transaction)
步骤1: Alice发送INVITE请求
INVITE sip:bob@example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Contact: <sip:alice@192.168.1.100:5060>
Content-Type: application/sdp
Content-Length: 245
v=0
o=alice 2890844526 2890844526 IN IP4 192.168.1.100
s=-
c=IN IP4 192.168.1.100
t=0 0
m=audio 5004 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
步骤2: Proxy服务器转发INVITE
INVITE sip:bob@192.168.1.200:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-proxy123
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Contact: <sip:alice@192.168.1.100:5060>
Content-Type: application/sdp
Content-Length: 245
[SDP内容与上面相同]
步骤3: Bob发送100 Trying(可选)
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-proxy123
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Content-Length: 0
步骤4: Bob发送180 Ringing
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-proxy123
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Contact: <sip:bob@192.168.1.200:5060>
Content-Length: 0
步骤5: Bob接听,发送200 OK
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-proxy123
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Contact: <sip:bob@192.168.1.200:5060>
Content-Type: application/sdp
Content-Length: 235
v=0
o=bob 2890844527 2890844527 IN IP4 192.168.1.200
s=-
c=IN IP4 192.168.1.200
t=0 0
m=audio 5006 RTP/AVP 0
a=rtpmap:0 PCMU/8000
步骤6: Alice发送ACK确认
ACK sip:bob@192.168.1.200:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-ack123
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
Call-ID: call-123456@192.168.1.100
CSeq: 1 ACK
Content-Length: 0
3.4.2 阶段2:媒体传输
此时SIP信令已完成会话建立,双方开始RTP媒体流传输:
Alice:192.168.1.100:5004 ←→ Bob:192.168.1.200:5006
RTP Audio Stream
3.4.3 阶段3:呼叫终止(BYE Transaction)
步骤1: Alice发送BYE请求
BYE sip:bob@192.168.1.200:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-bye123
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
Call-ID: call-123456@192.168.1.100
CSeq: 2 BYE
Content-Length: 0
步骤2: Bob响应200 OK
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-bye123
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
Call-ID: call-123456@192.168.1.100
CSeq: 2 BYE
Content-Length: 0
4. 关键信令字段深度分析
4.1 Call-ID:呼叫会话标识
Call-ID: call-123456@192.168.1.100
- 作用:唯一标识一个SIP会话
- 格式:通常包含本地标识符@主机地址
- 生命周期:从INVITE到BYE,整个会话期间保持不变
4.2 Via头域:路由追踪
Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-proxy123
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
- 作用:记录SIP消息的传输路径
- branch参数:RFC 3261要求以”z9hG4bK”开头
- 响应路由:响应消息沿Via头域记录的路径返回
4.3 From/To:呼叫方标识
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
- From tag:由发起方生成,标识发起方在此会话中的身份
- To tag:由接收方生成,在第一个最终响应中添加
- Dialog标识:Call-ID + From tag + To tag = 唯一会话标识
4.4 CSeq:命令序列号
CSeq: 1 INVITE
CSeq: 2 BYE
- 作用:标识请求的顺序,用于匹配请求和响应
- 格式:序列号 + 方法名
- 规则:同一会话中,序列号递增
4.5 Contact:实际联系地址
Contact: <sip:alice@192.168.1.100:5060>
- 作用:告诉对方如何直接联系自己
- 重要性:后续的BYE、re-INVITE等请求发送到此地址
- 区别:与From/To的逻辑地址不同,这是物理地址
5. SDP媒体协商分析
5.1 Alice的SDP Offer
v=0 # 版本
o=alice 2890844526 2890844526 IN IP4 192.168.1.100 # 发起者信息
s=- # 会话名称
c=IN IP4 192.168.1.100 # 连接信息
t=0 0 # 时间信息
m=audio 5004 RTP/AVP 0 8 # 媒体描述:音频,端口5004,支持codec 0和8
a=rtpmap:0 PCMU/8000 # codec 0 = PCMU,8kHz采样
a=rtpmap:8 PCMA/8000 # codec 8 = PCMA,8kHz采样
5.2 Bob的SDP Answer
v=0
o=bob 2890844527 2890844527 IN IP4 192.168.1.200
s=-
c=IN IP4 192.168.1.200
t=0 0
m=audio 5006 RTP/AVP 0 # 选择codec 0 (PCMU)
a=rtpmap:0 PCMU/8000
协商结果:
- 音频编码:PCMU (G.711 μ-law)
- Alice RTP端口:5004
- Bob RTP端口:5006
- 媒体流:双向音频
6. SIP会话状态转换
6.1 呼叫会话状态图
以下状态转换图展示了SIP呼叫过程中的各种状态及其转换关系:
[空闲] --INVITE--> [呼叫进行中] --180 Ringing--> [响铃中]
↓
[通话结束] <--BYE-- [通话中] <--200 OK + ACK-- [应答中]
↓
200 OK
上图中:
- 空闲:初始状态,尚未建立任何SIP对话
- 呼叫进行中:已发送INVITE,等待对方响应
- 响铃中:收到180 Ringing,表示被叫正在振铃
- 应答中:收到200 OK,表示被叫已接听
- 通话中:发送ACK后,双方建立会话进行通话
- 通话结束:一方发送BYE请求终止会话
6.2 关键流程节点说明
1. 注册阶段关键点:
- 用户必须先注册才能接收呼叫
- Proxy服务器维护用户位置数据库
- 注册有有效期,需要定期刷新
2. INVITE事务关键点:
- INVITE可能产生多个临时响应(1xx)
- 只有一个最终响应(2xx/3xx/4xx/5xx)
- ACK必须发送以完成三次握手
3. 媒体流关键点:
- RTP流是点对点传输,不经过Proxy
- 媒体参数通过SDP协商确定
- 支持双向实时音频传输
4. 会话终止关键点:
- 任何一方都可以发起BYE
- BYE直接发送,不经过Proxy
- 收到200 OK后会话正式结束
7. 异常流程处理
7.1 被叫忙线
SIP/2.0 486 Busy Here
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>;tag=bob456
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Content-Length: 0
7.2 被叫不在线
SIP/2.0 404 Not Found
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>
Call-ID: call-123456@192.168.1.100
CSeq: 1 INVITE
Content-Length: 0
7.3 呼叫取消(CANCEL)
CANCEL sip:bob@example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK-invite789
From: <sip:alice@example.com>;tag=alice789
To: <sip:bob@example.com>
Call-ID: call-123456@192.168.1.100
CSeq: 1 CANCEL
Content-Length: 0
8. 总结
SIP呼叫流程虽然看起来复杂,但其设计遵循了清晰的协议逻辑:
- 注册与呼叫独立:注册和呼叫是两个独立的过程,不是所有呼叫都需要先注册
- 会话建立:通过三次握手(INVITE→200 OK→ACK)建立会话
- 媒体传输:SIP只负责信令控制,媒体通过RTP直接传输
- 会话终止:使用BYE方法干净地释放资源
关键要点:
- SIP只负责信令控制,不传输媒体
- 每个SIP消息都包含完整的路由信息
- Via头域确保响应能正确返回
- Call-ID、From tag、To tag唯一标识一个会话
- SDP协商确定媒体参数
- 注册主要用于接收呼叫,而发起呼叫不一定需要注册
理解这些基本原理,就能够有效地设计、部署和维护SIP通信系统。在实际应用中,还需要考虑NAT穿越、负载均衡、安全性等复杂因素,但SIP协议的灵活性和扩展性为这些需求提供了良好的基础。