PTP协议精讲(2.12):PTP的十种语言——报文格式全解析

2.12 PTP的十种语言:报文格式全解析

如果PTP报文会说话

想象PTP报文是"信使",在网络中穿梭。

它们携带不同的"信件":

  • Sync:"主时钟说,现在是10:00:00.000000000秒"
  • Announce:"我是主时钟,我的clockClass是6,clockAccuracy是0x20"
  • Delay_Req:"请告诉我,你什么时候收到这条消息?"
  • Delay_Resp:"我在10:00:01.000000100秒收到你的请求"

每种报文都有特定的格式和用途。今天,我们就来"解读"PTP的十种报文。


PTP报文的分类

事件报文(Event Messages)

特点

  • 需要打时间戳
  • 精确性要求高
  • 通常由硬件处理

报文类型

报文 类型值 用途
Sync 0x0 携带时间信息
Delay_Req 0x1 请求延迟测量
Pdelay_Req 0x2 对等延迟测量请求
Pdelay_Resp 0x3 对等延迟测量响应

为什么需要时间戳?

这些报文用于时间同步和延迟测量,必须精确记录发送和接收时间。

通用报文(General Messages)

特点

  • 不需要打时间戳
  • 携带配置和状态信息
  • 可以由软件处理

报文类型

报文 类型值 用途
Follow_Up 0x8 携带精确时间戳(two-step模式)
Delay_Resp 0x9 延迟测量响应
Pdelay_Resp_Follow_Up 0xA 对等延迟测量精确时间戳
Announce 0xB 主时钟公告
Signaling 0xC 信令
Management 0xD 管理

公共报文头部:所有报文的"信封"

头部结构(34字节)

每个PTP报文都以一个34字节的公共头部开始。

字段 字节数 含义
majorSdoId + messageType 1 高4位:sdoId高位;低4位:报文类型
minorVersionPTP + versionPTP 1 高4位:次版本号;低4位:主版本号
messageLength 2 整个报文的字节数
domainNumber 1 域编号
minorSdoId 1 sdoId低位
flagField 2 标志位
correctionField 8 校正值
messageTypeSpecific 4 消息类型特定字段
sourcePortIdentity 10 发送端口的标识
sequenceId 2 序列号
controlField 1 控制字段(已过时)
logMessageInterval 1 消息间隔

关键字段详解

messageType(报文类型)

低4位标识报文类型:

  • 0x0:Sync
  • 0x1:Delay_Req
  • 0x2:Pdelay_Req
  • 0x3:Pdelay_Resp
  • 0x8:Follow_Up
  • 0x9:Delay_Resp
  • 0xA:Pdelay_Resp_Follow_Up
  • 0xB:Announce
  • 0xC:Signaling
  • 0xD:Management

高4位(majorSdoId)

用于域隔离(见2.3节)。

domainNumber + sdoId

domainNumber(1字节)+ majorSdoId(高4位)+ minorSdoId(1字节)= 完整的域标识。

flagField(标志位)

16位标志位,各位含义:

字节 名称 含义
0 0 alternateMasterFlag TRUE表示发送端口不在MASTER状态
0 1 twoStepFlag TRUE表示会有Follow_Up
0 2 unicastFlag TRUE表示单播
0 5-6 profileSpecific1/2 Profile定义
1 0 leap61 当月最后一分钟61秒
1 1 leap59 当月最后一分钟59秒
1 2 currentUtcOffsetValid UTC偏移有效
1 3 ptpTimescale TRUE表示PTP时间尺度
1 4 timeTraceable 时间可溯源
1 5 frequencyTraceable 频率可溯源
1 6 synchronizationUncertain 同步不确定

correctionField(校正字段)

8字节有符号整数,表示对报文的校正值。

单位2⁻¹⁶ 纳秒,即 1/65536 纳秒 ≈ 0.01526皮秒。

换算公式

  • correctionField → 秒seconds = correctionField / (65536 × 10⁹)
  • 纳秒部分nanoseconds = correctionField / 65536

示例

correctionField = 0x0000000000028000(十进制:163840)
值 = 163840 / 65536 = 2.5纳秒

用途

  • 携带小数纳秒部分
  • 透明时钟累加驻留时间
  • 路径不对称校正值

sourcePortIdentity(发送端口标识)

10字节

  • 前8字节:clockIdentity
  • 后2字节:portNumber

示例

clockIdentity = 00-1B-19-00-00-00-00-01
portNumber = 0x0001

sourcePortIdentity = 00-1B-19-00-00-00-00-01-00-01

sequenceId(序列号)

2字节,标识报文的序号。

用途

  • 关联Sync和Follow_Up
  • 关联Delay_Req和Delay_Resp
  • 检测丢包

各报文类型详解

Sync报文

格式

字段 字节数 累计
公共头部 34 34
originTimestamp 10 44

originTimestamp(10字节)

  • 6字节:秒部分(整数秒)
  • 4字节:纳秒部分

one-step模式

Sync报文的originTimestamp携带发送时间的整数秒部分,correctionField携带小数纳秒部分。

two-step模式

Sync报文的originTimestamp为0或估计值,精确时间戳由Follow_Up携带。


Follow_Up报文

格式

字段 字节数 累计
公共头部 34 34
preciseOriginTimestamp 10 44

preciseOriginTimestamp(10字节)

精确的Sync发送时间戳。

关联规则

Follow_Up报文的sequenceId必须与对应的Sync报文相同。


Delay_Req报文

格式

字段 字节数 累计
公共头部 34 34
originTimestamp 10 44
reserved 10 54

originTimestamp

标准规定设为0(因为从时钟发送时不知道自己时间的准确值)。

reserved字段

10字节保留字段,必须设为0。

为什么有保留字段?

为了与Pdelay_Req/Pdelay_Resp报文保持相同长度(54字节),简化硬件时间戳单元的设计。


Delay_Resp报文

格式

字段 字节数 累计
公共头部 34 34
receiveTimestamp 10 44
requestingPortIdentity 10 54

receiveTimestamp(10字节)

主时钟接收Delay_Req的时间。

requestingPortIdentity(10字节)

发送Delay_Req的端口标识(用于关联)。

示例

从时钟发送Delay_Req(sequenceId = 100)。
主时钟在1000.000001000秒接收Delay_Req。
主时钟发送Delay_Resp:

  • receiveTimestamp = 1000.000001000秒
  • requestingPortIdentity = 从时钟的portIdentity
  • sequenceId = 100

Pdelay_Req报文

格式

字段 字节数 累计
公共头部 34 34
originTimestamp 10 44
reserved 10 54

reserved字段

10字节保留字段,使报文长度与Pdelay_Resp一致。

用途

P2P机制中,测量两个端口之间的链路延迟。


Pdelay_Resp报文

格式

字段 字节数 累计
公共头部 34 34
requestReceiptTimestamp 10 44
requestingPortIdentity 10 54

requestReceiptTimestamp

响应者接收Pdelay_Req的时间(t2)。

one-step模式

Pdelay_Resp的correctionField携带(t3 - t2),即响应者的响应延迟。

two-step模式

Pdelay_Resp携带t2,Pdelay_Resp_Follow_Up携带t3。


Pdelay_Resp_Follow_Up报文

格式

字段 字节数 累计
公共头部 34 34
responseOriginTimestamp 10 44
requestingPortIdentity 10 54

responseOriginTimestamp

响应者发送Pdelay_Resp的时间(t3)。


Announce报文

格式

字段 字节数 累计
公共头部 34 34
originTimestamp 10 44
currentUtcOffset 2 46
reserved 1 47
grandmasterPriority1 1 48
grandmasterClockQuality 4 52
grandmasterPriority2 1 53
grandmasterIdentity 8 61
stepsRemoved 2 63
timeSource 1 64

grandmasterClockQuality(4字节)

子字段 字节数 含义
clockClass 1 时钟类别
clockAccuracy 1 时钟精度
offsetScaledLogVariance 2 方差(对数刻度)

stepsRemoved

到Grandmaster的边界时钟跳数。

timeSource

Grandmaster的时间源类型(如GNSS、原子钟)。

用途

  • 主时钟广播自己的信息
  • 用于BMCA决策
  • 传播时间属性(UTC偏移、闰秒等)

Signaling报文

格式

字段 字节数 累计
公共头部 34 34
targetPortIdentity 10 44
后缀(TLV序列) 可变 44+

用途

  • 单播协商
  • 路径追踪
  • 其他信令功能

后缀

一个或多个TLV(Type-Length-Value)实体。


Management报文

格式

字段 字节数 累计
公共头部 34 34
targetPortIdentity 10 44
startingBoundaryHops 1 45
boundaryHops 1 46
reserved 1 47
actionField 1 48
reserved 1 49
managementTLV 可变 49+

actionField

  • 0:GET(读取)
  • 1:SET(设置)
  • 2:RESPONSE(响应)
  • 3:COMMAND(命令)
  • 4:ACKNOWLEDGE(确认)

用途

  • 配置PTP设备
  • 查询状态
  • 故障诊断

报文长度汇总

报文类型 基础长度(字节) 备注
Sync 44 可加TLV
Delay_Req 54 可加TLV,含10字节保留
Follow_Up 44 可加TLV
Delay_Resp 54 可加TLV
Pdelay_Req 54 含10字节保留
Pdelay_Resp 54 可加TLV
Pdelay_Resp_Follow_Up 54 可加TLV
Announce 64 可加TLV,含1字节保留
Signaling 44+ 头部+TLV序列
Management 49+ 头部+管理TLV

一个完整的报文示例

Sync报文(one-step)

十六进制表示

00 00 00 2C    // majorSdoId=0, messageType=0x0(Sync), version=2.1, length=44
00 00 00 00    // domainNumber=0, minorSdoId=0
00 00          // flagField=0
00 00 00 00 00 00 00 00  // correctionField=0
00 00 00 00    // messageTypeSpecific=0
00 1B 19 00 00 00 00 01 00 01  // sourcePortIdentity
00 64          // sequenceId=100
00 00          // controlField=0, logMessageInterval=0
00 00 00 00 00 00 03 E8  // originTimestamp秒=1000
00 00 00 00    // originTimestamp纳秒=0

解读

  • 报文类型:Sync
  • PTP版本:2.1
  • 域:0
  • 发送端口:clockIdentity=00-1B-19-00-00-00-00-01, portNumber=1
  • 序列号:100
  • 发送时间:1000.000000000秒

Announce报文

十六进制表示(简化)

00 0B 00 40    // messageType=0xB(Announce), length=64
00 00 00 00    // domainNumber=0, minorSdoId=0, flagField=0
...
00 1B 19 00 00 00 00 01 00 01  // sourcePortIdentity
00 64          // sequenceId=100
...
00 00 00 00 00 00 00 00  // originTimestamp=0
00 25          // currentUtcOffset=37
00             // reserved
0A             // grandmasterPriority1=10
06 20 00 00    // clockClass=6, clockAccuracy=0x20, variance=0
0A             // grandmasterPriority2=10
00 1B 19 00 00 00 00 01  // grandmasterIdentity
00 00          // stepsRemoved=0
20             // timeSource=0x20(GNSS)

解读

  • 报文类型:Announce
  • 报文长度:64字节
  • 发送端口:clockIdentity=00-1B-19-00-00-00-00-01, portNumber=1
  • Grandmaster信息:
    • priority1=10, priority2=10
    • clockClass=6, clockAccuracy=0x20
    • timeSource=GNSS
  • stepsRemoved=0(发送者自己就是Grandmaster)

小结:PTP报文的核心要点

报文分类

  • 事件报文:需要时间戳(Sync、Delay_Req、Pdelay_Req、Pdelay_Resp)
  • 通用报文:不需要时间戳(Follow_Up、Delay_Resp、Pdelay_Resp_Follow_Up、Announce、Signaling、Management)

公共头部

  • 34字节
  • 包含报文类型、域标识、校正字段、发送端口等

关键报文

  • Sync:时间同步
  • Announce:主时钟公告
  • Delay_Req/Resp:E2E延迟测量
  • Pdelay系列:P2P延迟测量

报文关联

  • 通过sequenceId关联相关报文
  • 通过sourcePortIdentity标识发送者

报文长度要点

  • Sync/Follow_Up:44字节
  • Delay_Req/Pdelay系列:54字节
  • Announce:64字节

下集预告

PTP报文格式是固定的,但有时需要扩展功能。

下一节,我们将讲解TLV扩展机制——如何在固定格式基础上,灵活扩展PTP功能。

【悬念留给2.13】

你可能注意到:PTP报文有一个"后缀"部分,可以携带TLV。

TLV是什么?它能做什么?

  • PATH_TRACE TLV:记录报文经过的路径
  • CUMULATIVE_RATE_RATIO TLV:携带频率信息
  • AUTHENTICATION TLV:安全认证

下一节,我们详细解读TLV扩展机制。

📚 本文内容摘自本人的开源书《PTP技术书 - 从思想实验到协议实现》

全书从时间本质的思想实验出发,深度解析 IEEE 1588 协议、逐章分析 LinuxPTP 源码,并带你动手实现一个轻量级 PTP 程序(ptp-lite)。

🔗 在线阅读/下载:ptp-book

git clone https://github.com/Lularible/ptp-book.git

⭐ 如果对您有帮助,欢迎 Star 支持,也欢迎通过 GitHub Issues 交流讨论。

posted @ 2026-04-12 15:56  lularible  阅读(230)  评论(0)    收藏  举报