sip 协议是基于请求-响应模式的,客户端和服务器在发出请求时都等待对方的响应,其中一些请求很重要,在tcp/ip网络环境中由于ip包,防火墙,nat ,sbc,proxy 可能都在一路通话中存在,这些因素会影响呼叫。
sip call setup :invite --> 200 ok -->ACK
为了建立一个会话,客户端发起一个invite 事务,等待响应,当响应到达时(200 ok),客户端 返回ACK确认,这就是典型的三次握手,
由于在等待响应时,被叫可能振铃很长时间,协议栈必须确保在呼叫还没有建立起来前设备处于在线状态,所以在invite 和200 ok 之间会发生一下过程。
1. invite -> 100 trying
我们等待的第一个响应通常是 100 trying, 这个响应表明服务器已经收到明显合法的invite 请求(服务器收到请求后 先通过语法层检测消息的合法性),是一个临时响应,虽然服务器收到了invite 但被叫还没有被请求,即跟被叫还没关系。这里的服务器 可以是 sip终端,代理服务器(有状态代理)或者是sbc. 这里注意一点,客户端收到 100 trying 时 并不会响应 200 ok. 即 如果服务器发送 100trying 后不会等待这个响应的确认。
2. 服务器发送 100 临时应答后 会 代替客户端请求被叫,被叫 返回180 ringing 或183Session Progress ,服务器 转发给客户端,
这表明客户端的请求至少已经到达被叫的一个设备终端(服务器可能呼叫多个被叫的可达地址)。
3. 最后,被叫摘机,我们收到 一个 200 ok 响应,在这个响应中我们通过查看contact 头域可以知道被叫的直接联系地址。
4. 为了确认 我们可以与被叫建立联系,客户端返回 ack 确认给 contact 地址,如果这个ACK没有被被叫收到,那么此次呼叫失败。
5. 如果我们的invite 请求收到非 200应答,如 busy, rejected, 我们仍然发送 ack 确认我们已经收到invite请求的响应。
记住: 只有 invite请求 才有ACK确认,其他请求 如 prack, publish , 都没有!!!,其他请求只是基于请求 --响应,而没有ack, 没有三次握手,asterisk 里把 这种请求叫做 CRITICAL 请求。
asterisk sip中的qualify 参数 与sip 请求方法 OPTIONS 有关。
如果 在sip.conf 中开启 qualify ,asterisk 服务器会定时构造OPTIONS请求发给注册到上面的客户端来检测客户端的存活与否,
而且,如果服务器收不到请求的响应会重发,直到在指定时间内仍没有反应,此时服务器认为客户端不可达。