3、同步报文交互流程:Sync、Follow_Up、Delay_Req、Delay_Resp 四步握手过程详解
好,咱们今天来聊聊 PTP 协议里最核心的环节——四步握手。说白了,这就是主时钟和从时钟之间“对表”的完整流程。你想想看,两个设备要同步时间,总得有个你来我往的沟通机制吧?这四步握手就是干这个的。
我在项目里调试时间同步的时候,十次有八次的问题都出在这个流程上。要么是报文丢了,要么是时间戳打错了位置。所以,把这四步吃透,你基本就掌握了 PTP 的半壁江山。
3.1 第一步:Sync 报文——主时钟的“发令枪”
一切从 Sync 报文开始。主时钟会按照设定的周期(比如 125ms 一次),往网络上广播一个 Sync 报文。
这个报文里带什么信息呢?其实它只带了一个“大概”的时间。为什么说大概?因为 Sync 报文在离开主时钟网口的那一瞬间,硬件会打上一个精确的时间戳 t1。但这个 t1 通常不会塞进 Sync 报文本身里(除非是单步模式,咱们后面会讲)。
关键点:Sync 报文的主要作用就是告诉从时钟:“嘿,我准备开始同步了,你准备好接招!”
从时钟收到 Sync 报文时,也会在硬件层面打上一个到达时间戳 t2。这个 t2 非常精确,是后续计算延迟的基础。
我的经验:我曾经遇到过一个坑,就是 Sync 报文的发送周期设置得太快,导致从时钟的 CPU 处理不过来,丢包严重。后来我建议把周期从 125ms 改成 1s,问题就解决了。所以,周期设置要结合你的硬件处理能力来定。
3.2 第二步:Follow_Up 报文——把“精确时间”补上
Sync 报文发出去了,但精确的 t1 还没告诉从时钟呢。这时候,Follow_Up 报文就登场了。
主时钟在发出 Sync 报文后,会紧接着发一个 Follow_Up 报文。这个报文里就装着刚才那个精确的 t1 时间戳。
你可能会问:“为什么不直接把 t1 放在 Sync 报文里?” 嗯,这个问题问得好。原因很简单:硬件打时间戳需要时间。Sync 报文在离开网口的那一刻,硬件才捕获到 t1,这时候报文已经发出去了,来不及塞进去了。所以,只能靠后面的 Follow_Up 来补上。
核心逻辑:Sync 报文负责“触发”,Follow_Up 报文负责“补数据”。两者配合,从时钟就拿到了 (t1, t2) 这对时间戳。
从时钟收到 Follow_Up 后,就提取出 t1,再结合自己记录的 t2,就能算出主从之间的时间差了?别急,还差一步——路径延迟还没算呢。
3.3 第三步:Delay_Req 报文——从时钟的“反问”
前面两步,都是主时钟主动发,从时钟被动收。但路径延迟的计算,需要双向的测量。所以,从时钟得主动发一个报文给主时钟,这就是 Delay_Req。
从时钟在发出 Delay_Req 报文的那一刻,硬件也会打上一个精确的时间戳 t3。这个 t3 是从时钟本地记录的。
注意:Delay_Req 报文的发送时机不是随意的。从时钟通常会在收到 Sync/Follow_Up 后,随机延迟一段时间再发。这是为了避免多个从时钟同时发 Delay_Req 造成冲突。我曾经见过一个网络,几十个从时钟同时发 Delay_Req,直接把主时钟的网口打爆了。
主时钟收到 Delay_Req 报文时,也会在硬件层面打上到达时间戳 t4。现在,主时钟手里有了 t4,但 t3 还在从时钟手里。怎么办?
3.4 第四步:Delay_Resp 报文——主时钟的“回执”
最后一步,主时钟把刚才记录的 t4 时间戳,通过 Delay_Resp 报文发回给从时钟。
从时钟收到 Delay_Resp 后,就提取出 t4。现在,从时钟手里终于集齐了四个时间戳:t1、t2、t3、t4。
有了这四个时间戳,从时钟就能算出两个关键值:
- 主从时间差(Offset): 从时钟与主时钟之间的时间偏差。
- 路径延迟(Delay): 报文在主从之间往返一次的平均时间。
计算公式其实很简单:
假设网络是对称的(即主->从延迟 = 从->主延迟)
则:
平均路径延迟 = [(t2 - t1) + (t4 - t3)] / 2
时间偏差 = (t2 - t1) - 平均路径延迟
从时钟拿到这个时间偏差后,就可以调整自己的本地时钟,与主时钟保持同步了。
总结一下四步握手的本质:
- 主发 Sync,从记 t2,主记 t1(但 t1 稍后给)。
- 主发 Follow_Up,把 t1 告诉从。
- 从发 Delay_Req,从记 t3,主记 t4。
- 主发 Delay_Resp,把 t4 告诉从。
从时钟集齐 t1、t2、t3、t4,算出偏差和延迟,完成同步。
3.5 实战中的注意事项
嗯,这里我要多说几句。四步握手看起来简单,但在实际车载网络中,有几个地方特别容易出问题:
| 常见问题 | 原因 | 我的建议 |
|---|---|---|
| 时间戳精度不够 | 软件打戳代替硬件打戳 | 一定要用支持硬件时间戳的网卡,软件打戳误差在微秒级,根本没法用。 |
| Follow_Up 丢失 | 网络拥塞或优先级设置不当 | 把 PTP 报文的优先级设高,或者用 VLAN 隔离。 |
| Delay_Req 冲突 | 多个从时钟同时发送 | 设置随机延迟发送,或者用组播方式减少冲突。 |
| 网络不对称 | 主->从和从->主路径延迟不同 | 这是 PTP 的固有问题。如果不对称,算出来的延迟就是错的。可以用 gPTP(802.1AS)的邻居延迟机制来缓解。 |
避坑指南:我曾经在一个项目中,发现从时钟的时间总是跳变。排查了半天,发现是交换机的 E2E 透明时钟没配置好,导致 Sync 报文的驻留时间没被正确修正。从那以后,我每次调试都会先检查交换机的 PTP 配置。
好了,四步握手就讲到这里。你想想看,这四步其实就是一个“你来我往”的对话过程。主时钟说“我出发了”,然后补一句“我出发的时间是...”,从时钟说“我也出发了”,主时钟再回一句“你到达的时间是...”。就这么简单。
下一章,咱们会聊聊单步模式(One-Step)和双步模式(Two-Step)的区别。到时候你会发现,单步模式其实就是把 Follow_Up 合并到 Sync 里了,少了一步握手。