1. SIP协议基础:从零开始理解这个“打电话”的协议
大家好,我是你们这堂课的老朋友。今天咱们聊聊SIP协议。
说实话,我第一次接触SIP协议的时候,脑子里全是问号。这玩意儿到底是干嘛的?跟HTTP有啥区别?为什么搞通信的都在聊它?
后来我做了几个VoIP项目,踩了不少坑,才慢慢摸清楚它的脾气。今天我就把这些经验掰开了揉碎了讲给你听。
1.1 SIP协议到底是什么?
SIP,全称Session Initiation Protocol,会话初始协议。名字挺长,但说白了——它就是用来建立、修改和终止多媒体会话的“信令”协议。
你想想看,你拿起手机打电话,从拨号到对方接听,中间发生了什么?
- 你的手机要找到对方
- 要告诉对方“我想跟你通话”
- 要协商用什么编码(比如G.711还是Opus)
- 通话结束后要挂断
这些“幕后工作”,就是SIP协议干的。它不负责传输语音数据本身(那是RTP的事),它只负责“打招呼”和“说再见”。
核心理解:SIP = 信令控制,RTP = 媒体传输。两者分工明确,别搞混了。
1.2 SIP协议在网络通信中的角色
我习惯把SIP比作“电话总机”。你想想看,一个公司里,总机接线员负责什么?
- 接听来电,找到对应分机
- 转接电话
- 记录谁在线、谁不在
SIP在网络里干的就是这些事。它处在应用层,跟HTTP、FTP是平级的。但它不依赖具体传输层——可以用UDP,也可以用TCP,甚至TLS。
嗯,这里要注意:生产环境中,我强烈建议用TLS加密。为什么?因为SIP信令里会携带IP地址、用户名等信息,明文传输等于裸奔。我曾经在一个客户的网络里抓包,发现SIP消息里连密码都是明文的……那画面太美我不敢看。
1.3 SIP协议的基本组成元素
SIP网络里有几个“角色”,你得先认识它们。我画了一张图,帮你理清关系。
来,我一个个给你讲清楚。
1.3.1 用户代理(User Agent, UA)
UA就是终端设备。你的手机、电脑上的软电话、IP话机,都是UA。它分两部分:
- UAC(User Agent Client):发起请求的一方。比如你拨号,你的手机就是UAC。
- UAS(User Agent Server):接收请求的一方。对方手机响铃,它就是UAS。
注意:同一个设备可以同时扮演UAC和UAS。比如你在通话中,可以发起三方会议(此时是UAC),同时也能接听另一个来电(此时是UAS)。
1.3.2 代理服务器(Proxy Server)
这是SIP网络的核心。它负责路由请求、转发消息、做认证。
我举个例子:你给张三打电话,你的UA不知道张三在哪。于是把请求发给Proxy Server。Proxy Server查一下位置数据库,发现张三在另一个分公司,就把请求转发过去。
我的经验:Proxy Server有两种模式——有状态和无状态。有状态模式会记住每个会话的状态,适合做计费、鉴权。无状态模式转发完就忘,性能更高。生产环境中,我一般用有状态模式做入口,无状态模式做内部转发。
1.3.3 注册服务器(Registrar)
Registrar负责接收UA的注册请求。UA上线时,会发一个REGISTER消息,告诉Registrar:“我在这个IP地址,这个端口,我的URI是sip:zhangsan@company.com”。
Registrar把绑定关系写入位置数据库(Location Service)。这样别人找你时,Proxy Server就能查到你的位置。
嗯,这里有个坑:注册是有过期时间的。默认3600秒。如果UA没在过期前续约,Registrar就会删除绑定记录。我曾经遇到一个客户,他们的设备时钟不准,导致注册提前过期,电话打不进来。排查了半天才发现是这个问题。
1.3.4 其他重要元素
| 元素 | 作用 | 我的备注 |
|---|---|---|
| 重定向服务器 | 告诉UA“你要找的人现在在别处”,让UA自己去联系 | 适合做负载均衡,但会增加UA的复杂度 |
| B2BUA | 背靠背用户代理,完全控制会话两端 | 我在做SBC(会话边界控制器)时经常用到 |
| Presence Server | 管理用户在线状态(在线、忙碌、离开等) | 跟SIP的SUBSCRIBE/NOTIFY机制配合使用 |
1.4 SIP协议的核心功能
SIP能做的事,说白了就三件:注册、打电话、控制通话。我一个个说。
1.4.1 注册(Registration)
注册是SIP的第一步。没有注册,别人就找不到你。
注册流程很简单:
- UA发REGISTER请求给Registrar
- Registrar返回401 Unauthorized,要求认证(摘要认证)
- UA重新发REGISTER,带上认证信息
- Registrar验证通过,返回200 OK
代码示例?好,我给你看一个典型的REGISTER请求:
REGISTER sip:registrar.company.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: <sip:zhangsan@company.com>;tag=1928301774
To: <sip:zhangsan@company.com>
Call-ID: a84b4c76e66710@192.168.1.100
CSeq: 1 REGISTER
Contact: <sip:zhangsan@192.168.1.100:5060>
Expires: 3600
Content-Length: 0
注意看Contact字段,它告诉服务器“我在哪”。Expires字段告诉服务器“这个注册有效期多久”。
避坑指南:我曾经遇到一个案例,UA发的Contact里IP地址写的是内网IP,但实际通信需要经过NAT。结果注册成功了,但呼叫建立时媒体流不通。解决方案是在Contact里写公网IP,或者用STUN/TURN打洞。
1.4.2 呼叫建立(Call Setup)
这是SIP最核心的功能。一个典型的呼叫建立流程是这样的:
- 主叫UA发INVITE请求给Proxy Server
- Proxy Server查位置,转发给被叫UA
- 被叫UA响铃,返回180 Ringing
- 被叫接听,返回200 OK
- 主叫收到200 OK,发ACK确认
- 媒体通道建立(RTP开始传输)
你看,SIP只负责前5步。第6步是RTP的事。这就是我前面说的“分工明确”。
INVITE请求里会携带SDP(Session Description Protocol),用来协商媒体参数。比如:
INVITE sip:lisi@company.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK74bf9
Max-Forwards: 70
From: <sip:zhangsan@company.com>;tag=9fxced76sl
To: <sip:lisi@company.com>
Call-ID: 3848276298220188511@192.168.1.100
CSeq: 2 INVITE
Contact: <sip:zhangsan@192.168.1.100:5060>
Content-Type: application/sdp
Content-Length: 147
v=0
o=zhangsan 2890844526 2890844526 IN IP4 192.168.1.100
s=-
c=IN IP4 192.168.1.100
t=0 0
m=audio 49170 RTP/AVP 0 8
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
SDP里声明了:我用PCMU或PCMA编码,在192.168.1.100的49170端口收音频。对方收到后,如果支持这些编码,就选一个,然后回复自己的IP和端口。
1.4.3 呼叫控制(Call Control)
呼叫建立之后,SIP还能做很多事:
- 呼叫保持:发re-INVITE,把媒体流指向自己(或者指向一个保持音乐源)
- 呼叫转接:用REFER方法,把通话转给第三方
- 三方会议:用re-INVITE加入第三方
- 呼叫终止:任一方发BYE,对方回200 OK
我印象最深的是一个呼叫转接的坑。客户说转接后通话质量变差。我抓包一看,原来是转接后媒体流走了两个不同的路径,导致延迟增加。解决方案是在B2BUA层面做媒体中继,强制媒体流经过同一个节点。
1.5 小结
好了,这一章的内容就这些。我帮你捋一下重点:
- SIP是信令协议,负责建立、修改、终止会话
- 核心元素:UA(终端)、Proxy Server(路由)、Registrar(注册)、Location Service(位置)
- 三大功能:注册(REGISTER)、呼叫建立(INVITE/ACK)、呼叫控制(re-INVITE/BYE/REFER)
- SDP负责媒体协商,RTP负责媒体传输
下一章我们会深入SIP消息结构,包括请求行、状态行、头字段、消息体。到时候我会带你手撕SIP报文,看看里面到底藏了什么秘密。