17. 事务 (Transactions)
SIP是一个事务性协议:组件之间的交互发生在一系列独立的消息交换中。具体来说,SIP事务由单个请求和对该请求的任何响应组成,包括零个或多个临时响应和一个或多个最终响应。
事务定义
INVITE事务的特殊性:
- 在请求是INVITE的事务中(称为INVITE事务),事务还包括ACK,但仅当最终响应不是2xx响应时
- 如果响应是2xx,ACK不被视为事务的一部分
分离的原因: 这种分离的根源在于向UAC传递所有对INVITE的200 (OK)响应的重要性。为了将它们全部传递给UAC:
- UAS单独负责重传它们(参见第13.3.1.4节)
- UAC单独负责用ACK确认它们(参见第13.2.2.4节)
- 由于此ACK仅由UAC重传,它实际上被视为其自己的事务
事务的客户端和服务器端
事务有客户端和服务器端:
- 客户端事务 (Client Transaction): 发送请求
- 服务器事务 (Server Transaction): 发送响应
客户端和服务器事务是嵌入在任意数量元素中的逻辑功能。具体来说,它们存在于用户代理和有状态代理服务器中。
事务关系示例
+---------+ +---------+ +---------+ +---------+
| +-+|Request |+-+ +-+|Request |+-+ +-+|Request |+-+ |
| |C||------->||S| |C||------->||S| |C||------->||S| |
| |l|| ||e| |l|| ||e| |l|| ||e| |
| |i|| ||r| |i|| ||r| |i|| ||r| |
| |e|| ||v| |e|| ||v| |e|| ||v| |
| |n|| ||e| |n|| ||e| |n|| ||e| |
| |t|| ||r| |t|| ||r| |t|| ||r| |
| | || || | | || || | | || || | |
| |T|| ||T| |T|| ||T| |T|| ||T| |
| |r|| ||r| |r|| ||r| |r|| ||r| |
| |a|| ||a| |a|| ||a| |a|| ||a| |
| |n|| ||n| |n|| ||n| |n|| ||n| |
| |s||Response||s| |s||Response||s| |s||Response||s| |
| +-+|<-------|+-+ +-+|<-------|+-+ +-+|<-------|+-+ |
+---------+ +---------+ +---------+ +---------+
UAC Outbound Inbound UAS
Proxy Proxy
图4: 事务关系
无状态代理
无状态代理不包含客户端或服务器事务。 事务存在于一侧的UA或有状态代理与另一侧的UA或有状态代理之间。就SIP事务而言,无状态代理实际上是透明的。
客户端事务的目的
客户端事务的目的是:
- 从嵌入客户端的元素(称为"事务用户"或TU;它可以是UA或有状态代理)接收请求
- 可靠地将请求传递给服务器事务
- 接收响应并将它们传递给TU
- 过滤掉任何响应重传或不允许的响应(如对ACK的响应)
- 对于INVITE请求,负责为除2xx响应以外的任何最终响应生成ACK请求
服务器事务的目的
服务器事务的目的是:
- 从传输层接收请求并将它们传递给TU
- 过滤网络中的任何请求重传
- 从TU接受响应并将它们传递给传输层以在网络上传输
- 对于INVITE事务,吸收除2xx响应以外的任何最终响应的ACK请求
2xx响应和ACK的特殊处理
2xx响应及其ACK接受特殊处理:
- 此响应仅由UAS重传,其ACK仅由UAC生成
- 需要这种端到端处理,以便呼叫方知道接受呼叫的整套用户
- 由于这种特殊处理,2xx响应的重传由UA核心处理,而不是事务层
- 同样,2xx的ACK生成由UA核心处理
- 路径上的每个代理仅转发每个对INVITE的2xx响应及其相应的ACK
17.1 客户端事务 (Client Transaction)
客户端事务通过维护状态机提供其功能。
TU接口
TU通过简单接口与客户端事务通信:
- 当TU希望发起新事务时,它创建客户端事务
- 将要发送的SIP请求传递给它
- 传递要发送到的IP地址、端口和传输
- 客户端事务开始执行其状态机
- 有效响应从客户端事务向上传递给TU
两种类型的客户端事务
根据TU传递的请求方法,有两种类型的客户端事务状态机:
1. INVITE客户端事务:
- 处理INVITE请求的客户端事务
2. 非INVITE客户端事务:
- 处理除INVITE和ACK以外的所有请求的客户端事务
重要: 没有ACK的客户端事务。如果TU希望发送ACK,它将其直接传递给传输层进行传输。
INVITE事务的独特性
INVITE事务与其他方法的事务不同,因为其持续时间更长:
- 通常需要人工输入才能响应INVITE
- 发送响应预期的长延迟要求三次握手
- 另一方面,其他方法的请求预期快速完成
- 由于非INVITE事务依赖于两次握手,TU应该立即响应非INVITE请求
17.1.1 INVITE客户端事务
17.1.1.1 INVITE事务概述
INVITE事务由三次握手组成:
- 客户端事务发送INVITE
- 服务器事务发送响应
- 客户端事务发送ACK
重传机制
对于不可靠传输(如UDP):
- 客户端事务以从T1秒开始的间隔重传请求
- 每次重传后间隔加倍
- T1是往返时间(RTT)的估计,默认为500毫秒
- 几乎所有事务计时器都随T1缩放
- 更改T1会调整它们的值
对于可靠传输:
- 请求不会通过可靠传输重传
收到1xx响应后:
- 任何重传完全停止
- 客户端等待进一步的响应
- 服务器事务可以发送额外的1xx响应(服务器事务不可靠地传输这些响应)
最终响应:
- 最终,服务器事务决定发送最终响应
- 对于不可靠传输,该响应定期重传
- 对于可靠传输,它发送一次
- 对于在客户端事务收到的每个最终响应,客户端事务发送ACK,其目的是抑制响应的重传
17.1.1.2 正式描述(状态机)
INVITE客户端事务的状态机如图5所示。
初始状态:"Calling"
当TU用INVITE请求发起新客户端事务时,必须进入初始状态"Calling"。
进入Calling状态时:
- 客户端事务必须将请求传递给传输层进行传输
- 如果使用不可靠传输,客户端事务必须启动计时器A,值为T1
- 如果使用可靠传输,客户端事务不应该启动计时器A(计时器A控制请求重传)
- 对于任何传输,客户端事务必须启动计时器B,值为64*T1秒(计时器B控制事务超时)
计时器A触发(不可靠传输):
- 客户端事务必须通过将请求传递给传输层来重传请求
- 必须将计时器重置为2*T1的值
- 当计时器A在2*T1秒后再次触发时,请求必须再次重传(假设客户端事务仍处于此状态)
- 此过程必须继续,以便请求以每次传输后加倍的间隔重传
- 这些重传应该仅在客户端事务处于"Calling"状态时完成
T1值:
- 默认值为500毫秒
- T1是客户端和服务器事务之间RTT的估计
- 元素可以(虽然不推荐)在不允许一般互联网连接的封闭专用网络中使用更小的T1值
- T1可以选择更大,如果预先知道(例如在高延迟接入链路上)RTT更大,则推荐这样做
- 无论T1的值如何,必须使用本节中描述的重传的指数退避
计时器B触发:
- 如果当计时器B触发时客户端事务仍处于"Calling"状态,客户端事务应该通知TU已发生超时
- 客户端事务不得生成ACK
- 64*T1的值等于在不可靠传输的情况下发送七个请求所需的时间量
状态转换
1. Calling → Proceeding(收到临时响应):
- 如果客户端事务在"Calling"状态时收到临时响应,它转换到"Proceeding"状态
- 在"Proceeding"状态,客户端事务不应该再重传请求
- 此外,临时响应必须传递给TU
- 任何进一步的临时响应必须在"Proceeding"状态时向上传递给TU
2. Calling/Proceeding → Completed(收到300-699响应):
- 当处于"Calling"或"Proceeding"状态时,接收状态代码300-699的响应必须导致客户端事务转换到"Completed"
- 客户端事务必须将收到的响应向上传递给TU
- 客户端事务必须生成ACK请求,即使传输是可靠的
- 然后将ACK传递给传输层进行传输
- ACK必须发送到与原始请求发送到的相同地址、端口和传输
- 客户端事务应该在进入"Completed"状态时启动计时器D,对于不可靠传输值至少为32秒,对于可靠传输值为零秒
计时器D的目的:
- 计时器D反映当使用不可靠传输时服务器事务可以保持在"Completed"状态的时间量
- 这等于INVITE服务器事务中的计时器H,其默认值为64*T1
- 但是,客户端事务不知道服务器事务使用的T1值,因此使用32秒的绝对最小值,而不是基于T1的计时器D
在Completed状态接收响应重传:
- 在"Completed"状态接收的最终响应的任何重传必须导致ACK重新传递给传输层进行重传
- 但新收到的响应不得向上传递给TU
3. Calling/Proceeding → Terminated(收到2xx响应):
- 当处于"Calling"或"Proceeding"状态时,接收2xx响应必须导致客户端事务进入"Terminated"状态
- 响应必须向上传递给TU
- 此响应的处理取决于TU是代理核心还是UAC核心
- UAC核心将处理此响应的ACK生成
- 代理核心将始终向上游转发200 (OK)
- 代理和UAC之间200 (OK)的不同处理是它不在事务层处理的原因
4. Completed → Terminated(计时器D触发):
- 如果当客户端事务处于"Completed"状态时计时器D触发,客户端事务必须移动到Terminated状态
销毁客户端事务: 客户端事务必须在进入"Terminated"状态的瞬间被销毁。这实际上是保证正确操作所必需的。原因是对INVITE的2xx响应得到不同处理;每一个都由代理转发,UAC中的ACK处理不同。因此,每个2xx需要传递给代理核心(以便可以转发)和UAC核心(以便可以确认)。不进行事务层处理。
INVITE客户端事务状态图
|INVITE from TU
Timer A fires |INVITE sent
Reset A, V Timer B fires
INVITE sent +-----------+ or Transport Err.
+---------| |---------------+inform TU
| | Calling | |
+-------->| |-------------->|
+-----------+ 2xx |
| | 2xx to TU |
| |1xx |
300-699 +---------------+ |1xx to TU |
ACK sent | | |
resp. to TU | 1xx V |
| 1xx to TU -----------+ |
| +---------| | |
| | |Proceeding |-------------->|
| +-------->| | 2xx |
| +-----------+ 2xx to TU |
| 300-699 | |
| ACK sent, | |
| resp. to TU| |
| | |
| 300-699 V |
| ACK sent +-----------+Transport Err. |
| +---------| |Inform TU |
| | | Completed |-------------->|
| +-------->| | |
| +-----------+ |
| ^ | |
| | | Timer D fires |
+--------------+ | - |
| |
V |
+-----------+ |
| | |
| Terminated|<--------------+
| |
+-----------+
图5: INVITE客户端事务
17.1.1.3 ACK请求的构造
本节指定在客户端事务内发送的ACK请求的构造。为2xx生成ACK的UAC核心必须遵循第13节中描述的规则。
ACK请求必须包含的头字段值:
- Call-ID, From, Request-URI: 等于客户端事务传递给传输的请求中这些头字段的值(称为"原始请求")
- To: ACK中的To头字段必须等于被确认的响应中的To头字段,因此通常会通过添加标签参数而与原始请求中的To头字段不同
- Via: ACK必须包含单个Via头字段,这必须等于原始请求的顶部Via头字段
- CSeq: ACK中的CSeq头字段必须包含与原始请求中相同的序列号值,但方法参数必须等于"ACK"
Route头字段: 如果被确认响应的INVITE请求有Route头字段,这些头字段必须出现在ACK中。这是为了确保ACK可以通过任何下游无状态代理正确路由。
消息体: 虽然任何请求都可能包含消息体,但ACK中的消息体是特殊的,因为如果不理解消息体,请求不能被拒绝。因此,不推荐在非2xx的ACK中放置消息体,但如果这样做,消息体类型仅限于INVITE中出现的任何类型,假设对INVITE的响应不是415。如果是415,ACK中的消息体可以是415中Accept头字段中列出的任何类型。
ACK示例:
原始INVITE:
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:[email protected]>
From: Alice <sip:[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
CSeq: 986759 INVITE
对非2xx最终响应的ACK:
ACK sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:[email protected]>;tag=99sa0xk
From: Alice <sip:[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
CSeq: 986759 ACK
17.1.2 非INVITE客户端事务
17.1.2.1 非INVITE事务概述
非INVITE事务不使用ACK。它们使用简单的请求-响应模型。这种差异的原因是INVITE请求建立会话,可能需要很长时间才能完成。对于非INVITE请求,预期会快速完成。
17.1.2.2 正式描述(状态机)
非INVITE客户端事务的状态机比INVITE事务简单。
初始状态:"Trying"
当TU发起新客户端事务时,必须进入初始状态"Trying"。
进入Trying状态时:
- 客户端事务必须将请求传递给传输层进行传输
- 如果使用不可靠传输,客户端事务必须启动计时器E,初始值为T1
- 如果使用可靠传输,客户端事务不应该启动计时器E
- 对于任何传输,客户端事务必须启动计时器F,值为64*T1秒
计时器E触发(不可靠传输):
- 请求必须重传
- 计时器E必须重置为2*T1
- 每次后续触发时,计时器值加倍(4T1, 8T1, ...)
- 计时器E的最大值为T2(默认4秒)
- 一旦达到T2,以T2间隔继续重传
计时器F触发:
- 如果客户端事务仍处于"Trying"状态,客户端事务应该通知TU已发生超时
- 客户端事务必须转换到Terminated状态
状态转换
1. Trying → Proceeding(收到临时响应):
- 如果客户端事务在"Trying"状态时收到临时响应(100-199),它转换到"Proceeding"状态
- 临时响应必须传递给TU
- 任何进一步的临时响应必须传递给TU
- 在"Proceeding"状态,如果使用不可靠传输,仍然必须继续重传(由计时器E控制)
2. Trying/Proceeding → Completed(收到最终响应):
- 当收到最终响应(200-699)时,客户端事务转换到"Completed"状态
- 响应必须传递给TU
- 客户端事务必须启动计时器K,值为T4(对于不可靠传输为5秒,对于可靠传输为0秒)
- 计时器K的目的是吸收最终响应的任何重传
3. Completed → Terminated(计时器K触发):
- 当计时器K触发时,客户端事务转换到Terminated状态
- 客户端事务必须被销毁
非INVITE客户端事务状态图
|Request from TU
|send request
Timer E V
send request +-----------+
+--------| |-------------------+
| | Trying | Timer F |
+------->| | or Transport Err.|
+-----------+ inform TU |
| | |
| |Timer E |
| |send req |
200-699 | | |
resp. to TU | |1xx |
+-------------------+ |resp. to TU |
| | |
| Timer E V |
| send req +-----------+ |
| +-----------+ | |
| | |Proceeding |------------------>|
| +---------->| |Timer F |
| +-----------+or Transport Err. |
| | ^ inform TU |
| | | |
| | +--------+ |
| 200-699 | |1xx |
| resp. to TU | |resp. to TU |
| V | |
| +-----------+ | |
| | | | |
| | Completed | | |
| | | | |
| +-----------+ | |
| | | |
| |Timer K | |
| |- | |
| | | |
| V | |
| +-----------+ | |
| | | | |
+------------>| Terminated|<--------+------------+
| |
+-----------+
图6: 非INVITE客户端事务
17.1.3 将响应匹配到客户端事务
当传输层收到响应时,它必须检查响应的顶部Via头字段值。如果此Via头字段值指示发送消息的主机(等于此主机的主机、域或IP地址),响应的下一步将是事务层。
事务匹配规则: 响应匹配客户端事务的条件:
- 响应的CSeq方法必须与发送请求中的方法匹配
- 响应的顶部Via头字段的分支参数必须等于请求的顶部Via头字段的分支参数
- 响应的顶部Via头字段的sent-by值必须等于请求的顶部Via头字段的sent-by值(作为后备)
ACK的特殊情况:
- CANCEL形成自己的事务
- 但对它的响应将匹配原始INVITE的客户端事务
- 这不会产生问题,因为CANCEL事务的TU(无论是代理还是UAC)在收到对CANCEL的1xx/2xx时会忽略它们
17.1.4 处理传输错误
当客户端事务向传输层发送请求时,如果传输层指示失败,客户端事务必须:
- 通知TU传输失败已发生
- 如果客户端事务不在"Completed"状态,转换到"Terminated"状态
- 客户端事务必须被销毁
17.2 服务器事务 (Server Transaction)
服务器事务的状态机比客户端事务简单。
TU接口
服务器事务通过简单接口与TU通信:
- 当请求从传输层到达时,服务器事务被创建
- 请求传递给TU
- TU将响应传递给服务器事务
- 服务器事务负责可靠地传递响应
17.2.1 INVITE服务器事务
INVITE服务器事务的目的是:
- 可靠地接收INVITE请求
- 传递给TU
- 可靠地发送响应
- 吸收ACK
状态机
初始状态:"Proceeding"
当从传输层收到INVITE请求时,服务器事务创建并进入"Proceeding"状态。
进入Proceeding状态时:
- 服务器事务必须将请求传递给TU
- TU处理请求并生成响应
- 如果使用不可靠传输,服务器事务必须启动计时器G(初始值T1)
- 如果使用可靠传输,不启动计时器G
在Proceeding状态:
- 如果收到请求的重传,服务器事务必须将最后发送的响应传递给传输层进行重传
- 服务器事务必须通过计时器G重传临时响应(如果使用不可靠传输)
状态转换
1. Proceeding → Completed(发送300-699响应):
- 当TU传递300-699响应时,服务器事务转换到"Completed"状态
- 响应必须传递给传输层进行传输
- 如果使用不可靠传输,服务器事务必须启动计时器H,值为64*T1
- 计时器G必须停止
在Completed状态:
- 服务器事务等待INVITE的ACK
- 如果收到请求重传,服务器事务必须重传最终响应
- 如果收到ACK,服务器事务吸收它(不传递给TU)
- 如果使用不可靠传输,服务器事务必须启动计时器I,值为T4(5秒)
- 如果使用可靠传输,计时器I值为0秒
2. Completed → Confirmed(收到ACK):
- 收到ACK时,服务器事务转换到"Confirmed"状态
- 启动计时器I
3. Completed/Confirmed → Terminated:
- 如果计时器H触发(未收到ACK),服务器事务转换到Terminated状态
- 如果计时器I触发,服务器事务转换到Terminated状态
- 服务器事务必须被销毁
4. Proceeding → Terminated(发送2xx响应):
- 当TU传递2xx响应时,服务器事务必须将其传递给传输层进行传输
- 然后转换到"Terminated"状态
- 2xx响应的重传由TU处理,不是服务器事务
INVITE服务器事务状态图
|INVITE
|pass INV to TU
INVITE V send 100 if TU won't in 200ms
send response+-----------+
+--------| |--------+101-199 from TU
| | Proceeding| |send response
+------->| |<-------+
+-----------+
| |
| |Timer G fires
| |send response
300-699 from TU | |
send response | |
| V
| +-----------+
| | |
+->| Completed |<----------+
| | |
+--| |---+Timer H fires
| +-----------+ |or Transport Err.
ACK | | |Inform TU
- | |Timer G fires|
| |send response|
V | |
+-----------+ |
| | |
| Confirmed | |
| | |
+-----------+ |
| |
|Timer I fires |
|- |
| |
V |
+-----------+ |
| | |
| Terminated|<-----------+
| |
+-----------+
图7: INVITE服务器事务
17.2.2 非INVITE服务器事务
非INVITE服务器事务比INVITE服务器事务简单得多。
状态机
初始状态:"Trying"
当从传输层收到非INVITE请求时,服务器事务创建并进入"Trying"状态。
进入Trying状态时:
- 服务器事务必须将请求传递给TU
- 一旦TU传递响应,服务器事务必须转换到"Completed"状态
在Trying状态:
- 如果收到请求的重传,服务器事务必须将最后发送的响应(如果有)传递给传输层进行重传
状态转换
1. Trying → Proceeding(TU发送临时响应):
- 当TU传递临时响应时,服务器事务转换到"Proceeding"状态
- 响应必须传递给传输层进行传输
2. Trying/Proceeding → Completed(TU发送最终响应):
- 当TU传递最终响应时,服务器事务转换到"Completed"状态
- 响应必须传递给传输层进行传输
- 服务器事务必须启动计时器J,值为64*T1(对于不可靠传输)或0秒(对于可靠传输)
在Completed状态:
- 服务器事务必须将最终响应传递给传输层以重传,如果收到请求的任何重传
- 服务器事务不能从TU接收任何其他响应
3. Completed → Terminated(计时器J触发):
- 当计时器J触发时,服务器事务转换到Terminated状态
- 服务器事务必须被销毁
非INVITE服务器事务状态图
|Request received
|pass to TU
V
+-----------+
| |
| Trying |----------+200-699 from TU
| | |send response
+-----------+ |
| |
|1xx from TU |
|send response |
V |
+-----------+ |
| | |
| Proceeding|----------+200-699 from TU
| | |send response
+-----------+ |
|
|
V
+-----------+
| |
| Completed |
| |
+-----------+
|
|Timer J fires
|-
|
V
+-----------+
| |
| Terminated|
| |
+-----------+
图8: 非INVITE服务器事务
17.2.3 将请求匹配到服务器事务
当传输层收到请求时,它必须检查该请求是否匹配现有服务器事务。
事务匹配规则: 请求匹配服务器事务的条件:
- 请求的Request-URI、To标签、From标签、Call-ID、CSeq号和顶部Via分支参数必须匹配事务请求中相应的值
- 请求方法必须匹配事务的方法(CANCEL和ACK除外)
ACK匹配:
- 对非2xx最终响应的ACK匹配生成该响应的INVITE事务
- ACK的Request-URI、To标签、From标签、Call-ID、CSeq号(不是方法)和顶部Via分支参数必须匹配INVITE事务
CANCEL匹配:
- CANCEL不匹配任何事务
- CANCEL创建自己的服务器事务
- TU使用CANCEL的Request-URI、To标签、From标签、Call-ID、CSeq号和顶部Via分支参数来查找要取消的INVITE事务
17.2.4 处理传输错误
如果传输层通知服务器事务传输错误,服务器事务必须:
- 通知TU传输失败
- 转换到"Terminated"状态
- 服务器事务必须被销毁
📊 事务计时器总结
| 计时器 | 用途 | 默认值 | 适用 |
|---|---|---|---|
| Timer A | INVITE请求重传 | 初始T1, 每次加倍 | INVITE客户端事务(不可靠传输) |
| Timer B | INVITE事务超时 | 64*T1 | INVITE客户端事务 |
| Timer D | 等待响应重传 | ≥32秒(不可靠),0秒(可靠) | INVITE客户端事务Completed状态 |
| Timer E | 非INVITE请求重传 | 初始T1, 加倍至T2 | 非INVITE客户端事务(不可靠传输) |
| Timer F | 非INVITE事务超时 | 64*T1 | 非INVITE客户端事务 |
| Timer K | 等待响应重传 | T4(不可靠),0秒(可靠) | 非INVITE客户端事务Completed状态 |
| Timer G | INVITE响应重传 | 初始T1, 每次加倍 | INVITE服务器事务(不可靠传输) |
| Timer H | ACK接收等待 | 64*T1 | INVITE服务器事务Completed状态 |
| Timer I | ACK重传吸收 | T4(不可靠),0秒(可靠) | INVITE服务器事务Confirmed状态 |
| Timer J | 请求重传吸收 | 64*T1(不可靠),0秒(可靠) | 非INVITE服务器事务Completed状态 |
基本计时器值:
- T1: 500ms(RTT估计,可调整)
- T2: 4秒(最大重传间隔)
- T4: 5秒(网络保持时间)
关键要点
- INVITE事务使用三次握手:请求、响应、ACK
- 非INVITE事务使用两次握手:请求、响应
- 2xx响应及其ACK的特殊处理:不由事务层处理,而是由UA核心处理
- 可靠传输vs不可靠传输:计时器行为不同
- 事务匹配:基于分支参数、CSeq、Call-ID等
- 状态机驱动:所有事务行为由状态机定义
- 指数退避:重传间隔指数增长,最大到T2
本章小结:
第17章详细描述了SIP事务层的完整规范,包括客户端事务和服务器事务的状态机、计时器机制、请求/响应匹配规则。事务层是SIP协议栈的核心,负责提供可靠的消息传递。INVITE事务和非INVITE事务有显著差异,前者使用三次握手并有更复杂的状态机,后者使用两次握手。理解事务层对于实现健壮的SIP应用至关重要。