Fast-DDS 源码分析(一):架构总览与模块介绍
系列规划:本文是 Fast-DDS 源码分析系列的开篇,对整体架构和各模块进行概要介绍。后续文章将逐一深入剖析各个核心模块。
目录
- [一、Fast-DDS 简介](#一、Fast-DDS 简介)
- [1.1 技术栈](#1.1 技术栈)
- 二、顶层目录结构
- [三、核心设计:双层 API 架构](#三、核心设计:双层 API 架构)
- [3.1 为什么设计两层?](#3.1 为什么设计两层?)
- [3.2 桥接模式(Bridge Pattern)](#3.2 桥接模式(Bridge Pattern))
- [四、DDS 层核心实体](#四、DDS 层核心实体)
- [4.1 实体层次结构](#4.1 实体层次结构)
- [4.2 关键类职责](#4.2 关键类职责)
- [4.3 典型使用流程](#4.3 典型使用流程)
- [五、RTPS 层模块详解](#五、RTPS 层模块详解)
- [5.1 模块全景图](#5.1 模块全景图)
- [5.2 核心类继承层次](#5.2 核心类继承层次)
- [5.3 发现协议(Discovery Protocol)](#5.3 发现协议(Discovery Protocol))
- [PDP --- 参与者发现](#PDP — 参与者发现)
- [EDP --- 端点发现](#EDP — 端点发现)
- 发现流程
- [5.4 消息发送与接收流程](#5.4 消息发送与接收流程)
- [发送路径(Writer → 网络)](#发送路径(Writer → 网络))
- [接收路径(网络 → Reader)](#接收路径(网络 → Reader))
- [5.5 关键设计要点](#5.5 关键设计要点)
- [六、传输层(Transport Layer)](#六、传输层(Transport Layer))
- [6.1 传输类层次](#6.1 传输类层次)
- [6.2 各传输方式特点](#6.2 各传输方式特点)
- [6.3 SHM 传输原理](#6.3 SHM 传输原理)
- [6.4 传输注册机制](#6.4 传输注册机制)
- [七、安全模块(DDS Security)](#七、安全模块(DDS Security))
- 八、其他重要模块
- [8.1 流控制(FlowController)](#8.1 流控制(FlowController))
- [8.2 历史缓存(History)](#8.2 历史缓存(History))
- [8.3 持久化(Persistence)](#8.3 持久化(Persistence))
- [8.4 统计与监控(Statistics)](#8.4 统计与监控(Statistics))
- [8.5 X-Types 动态类型](#8.5 X-Types 动态类型)
- [8.6 RPC(Request-Reply)](#8.6 RPC(Request-Reply))
- 九、系列文章规划
- 十、阅读源码的建议
一、Fast-DDS 简介
Fast-DDS (原名 Fast RTPS)是 eProsima 公司开源的 DDS(Data Distribution Service,数据分发服务)中间件实现,采用 Apache 2.0 许可证。它是:
- OMG DDS 标准的 C++ 高性能实现
- ROS 2(Robot Operating System 2)的默认通信中间件
- 支持实时数据分发、发布-订阅模式、QoS 策略、安全加密等
技术栈
| 维度 | 详情 |
|---|---|
| 语言 | C++(C++11 起) |
| 构建 | CMake(>= 3.22) |
| 序列化 | Fast-CDR(CDR 标准序列化) |
| 内存 | foonathan_memory(高效内存分配器) |
| 网络 | Asio + 原生 Socket(UDP/TCP/SHM) |
| XML | TinyXML2 |
| 安全 | OpenSSL(可选) |
二、顶层目录结构

Fast-DDS-master/
├── CMakeLists.txt # 顶层 CMake 构建文件
├── include/fastdds/ # 公共头文件(对外 API)
│ ├── dds/ # DDS 高层 API(发布-订阅模型)
│ └── rtps/ # RTPS 底层 API(写入者-读取者模型)
├── src/cpp/ # 源码实现
│ ├── fastdds/ # DDS 层实现
│ ├── rtps/ # RTPS 协议层实现
│ ├── security/ # DDS Security 安全插件
│ ├── statistics/ # 统计与监控模块
│ ├── utils/ # 工具函数
│ └── xmlparser/ # XML 配置解析
├── examples/cpp/ # 13 个 C++ 示例
├── test/ # 单元测试和集成测试
├── thirdparty/ # 第三方依赖
├── tools/ # 辅助工具
├── fuzz/ # 模糊测试
└── resources/ # XSD 模式等资源文件
三、核心设计:双层 API 架构
Fast-DDS 最核心的设计特点是 两层 API 架构,这是理解整个项目的关键。

┌─────────────────────────────────────────────────────┐
│ 用户应用 │
├─────────────────────────────────────────────────────┤
│ DDS 层(高层 API) │
│ DomainParticipant / Publisher / Subscriber │
│ DataWriter / DataReader / Topic │
│ ── 发布-订阅模型,符合 OMG DDS 标准 │
├─────────────────────────────────────────────────────┤
│ RTPS 层(底层 API) │
│ RTPSParticipant / RTPSWriter / RTPSReader │
│ ── 写入者-读取者模型,直接操作 RTPS 协议 │
├─────────────────────────────────────────────────────┤
│ 传输层 │
│ UDP / TCP / Shared Memory Transport │
└─────────────────────────────────────────────────────┘
为什么设计两层?
| DDS 层 | RTPS 层 | |
|---|---|---|
| 抽象级别 | 面向应用的发布-订阅 | 面向协议的写入者-读取者 |
| 符合标准 | OMG DDS 规范 | OMG RTPS 规范 |
| 实体管理 | DomainParticipant 统一管理 | 各自独立创建 |
| 适用场景 | 大多数应用开发 | 需要精细控制协议行为 |
桥接模式(Bridge Pattern)
DDS 层实体在内部持有 RTPS 层实体的指针,通过委托模式实现桥接:
| DDS 实体 | 内部持有的 RTPS 实体 |
|---|---|
DomainParticipant → |
RTPSParticipant* |
Publisher → |
共享 DomainParticipant 的 RTPSParticipant* |
Subscriber → |
共享 DomainParticipant 的 RTPSParticipant* |
DataWriter → |
BaseWriter*(RTPSWriter 的基类) |
DataReader → |
RTPSReader* |
Topic → |
无直接 RTPS 对应(纯 DDS 概念) |
四、DDS 层核心实体
实体层次结构

Entity(抽象基类)
├── DomainEntity
│ └── DomainParticipant ← 域的入口,管理所有实体
│ ├── 创建 Publisher
│ ├── 创建 Subscriber
│ └── 创建 Topic
├── Publisher ← 创建和管理 DataWriter
│ └── DataWriter ← 发布数据
├── Subscriber ← 创建和管理 DataReader
│ └── DataReader ← 订阅数据
├── Topic ← 数据主题
├── ContentFilteredTopic ← 内容过滤主题
└── DomainParticipantFactory ← 单例工厂,创建 DomainParticipant
关键类职责
| 类 | 头文件 | 职责 |
|---|---|---|
DomainParticipantFactory |
dds/domain/DomainParticipantFactory.hpp |
单例工厂,管理所有 DomainParticipant |
DomainParticipant |
dds/domain/DomainParticipant.hpp (64KB) |
域参与者,应用的入口点 |
Publisher |
dds/publisher/Publisher.hpp (19KB) |
发布者,管理 DataWriter 集合 |
Subscriber |
dds/subscriber/Subscriber.hpp (20KB) |
订阅者,管理 DataReader 集合 |
DataWriter |
dds/publisher/DataWriter.hpp (27KB) |
数据写入者,发布数据 |
DataReader |
dds/subscriber/DataReader.hpp (59KB) |
数据读取者,订阅数据 |
Topic |
dds/topic/Topic.hpp |
主题,定义数据的名称和类型 |
TypeSupport |
dds/topic/TypeSupport.hpp (16KB) |
类型支持,处理序列化/反序列化 |
典型使用流程
cpp
// 1. 创建 DomainParticipant
auto participant = DomainParticipantFactory::get_instance()
->create_participant(0, PARTICIPANT_QOS_DEFAULT);
// 2. 注册类型
TypeSupport type(new MyDataTypePubSubType());
type.register_type(participant, "MyDataType");
// 3. 创建 Topic
auto topic = participant->create_topic("MyTopic", "MyDataType", TOPIC_QOS_DEFAULT);
// 4. 创建 Publisher 和 DataWriter
auto publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
auto writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
// 5. 创建 Subscriber 和 DataReader
auto subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
auto reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
// 6. 发布数据
MyDataType data;
writer->write(&data);
// 7. 订阅数据
MyDataType received_data;
SampleInfo info;
reader->take_next_sample(&received_data, &info);
五、RTPS 层模块详解
RTPS 层是 Fast-DDS 的核心,包含 17 个子模块。
5.1 模块全景图

src/cpp/rtps/
├── participant/ # RTPSParticipant 实现
├── writer/ # Writer 层次(Stateful/Stateless/Persistent)
├── reader/ # Reader 层次(Stateful/Stateless/Persistent)
├── builtin/ # 内置协议
│ └── discovery/ # 发现协议(PDP + EDP)
│ ├── participant/ # PDP:参与者发现
│ ├── endpoint/ # EDP:端点发现
│ └── database/ # 发现数据库(Discovery Server)
├── messages/ # RTPS 消息构造与解析
├── network/ # 网络工厂(NetworkFactory)
├── transport/ # 传输层(UDP/TCP/SHM)
├── flowcontrol/ # 流控制器
├── history/ # 历史缓存(CacheChange)
├── common/ # 通用类型(GUID/SequenceNumber/CacheChange/Time_t)
├── attributes/ # 属性定义
├── DataSharing/ # 数据共享(共享内存零拷贝)
├── domain/ # RTPSDomain 工厂
├── security/ # 安全插件接口
├── persistence/ # 持久化服务
├── resources/ # 资源管理(定时器/事件)
└── exceptions/ # RTPS 异常
5.2 核心类继承层次
Endpoint(端点)
Endpoint
├── RTPSWriter(抽象接口)
│ └── BaseWriter
│ ├── StatefulWriter ← 可靠通信(RELIABLE)
│ │ └── StatefulPersistentWriter
│ └── StatelessWriter ← 尽力而为(BEST_EFFORT)
│ └── StatelessPersistentWriter
│
└── RTPSReader(抽象接口)
└── BaseReader
├── StatefulReader ← 可靠通信
│ └── StatefulPersistentReader
└── StatelessReader ← 尽力而为
└── StatelessPersistentReader
Stateful vs Stateless 的核心区别:
| Stateful | Stateless | |
|---|---|---|
| QoS | RELIABLE | BEST_EFFORT |
| Writer 侧 | 维护 ReaderProxy 列表,跟踪每个 Reader 的接收状态 |
仅维护 ReaderLocator 列表 |
| Reader 侧 | 维护 WriterProxy 列表,跟踪序列号 |
不维护 Writer 状态 |
| 可靠性保证 | ACKNACK 确认 + 重传机制 | 无保证 |
| 内存开销 | 较高 | 较低 |
Participant
RTPSParticipant(公共 API 外观类)
└── RTPSParticipantImpl(实际实现)
├── 持有 BuiltinProtocols*
├── 持有 NetworkFactory
├── 持有 m_allWriterList / m_allReaderList
├── 持有 send_resource_list_ / m_receiverResourcelist
└── 管理 FlowControllerFactory
5.3 发现协议(Discovery Protocol)
发现协议是 DDS 自动发现和匹配的核心,分为两层:
PDP(Participant Discovery Protocol)--- 参与者发现
PDP(抽象基类)
├── PDPSimple ← 标准 SimplePDP(多播 BEST_EFFORT)
├── PDPClient ← Discovery Server 客户端
└── PDPServer ← Discovery Server 服务端
- 使用 SPDP(Simple PDP) 内置 Writer/Reader 交换
DATA(p)子消息 PDPSimple通过多播宣告自身存在PDPClient/Server通过单播 RELIABLE 通信,配合DiscoveryDataBase维护全局发现信息
EDP(Endpoint Discovery Protocol)--- 端点发现
EDP(抽象基类)
├── EDPSimple ← 标准 SimpleEDP(RELIABLE)
│ └── EDPServer ← Discovery Server 端点发现
├── EDPStatic ← 静态发现(XML 配置,无网络流量)
└── EDPClient ← Discovery Server 客户端 EDP
- 使用 SEDP(Simple EDP) 内置 Writer/Reader 交换
DATA(w)和DATA(r)子消息 validMatching()方法检查 QoS 兼容性、Topic 匹配、Partition 匹配、TypeInfo 兼容性EDPStatic从 XML 文件读取端点信息,适用于静态配置场景
发现流程

1. PDP::announceParticipantState()
→ SPDP Writer 发送 DATA(p)(多播或单播到 Discovery Server)
2. 远程 PDP 接收 DATA(p)
→ createParticipantProxyData()
→ assignRemoteEndpoints() → 匹配 SPDP/SEDP 内置端点
3. EDP::assignRemoteEndpoints()
→ 遍历远程参与者代理数据
→ pairingWriter() / pairingReader() → validMatching()
→ matched_writer_add() / matched_reader_add()
4. 本地 EDP 注册端点时
→ EDP::new_writer_proxy_data() / new_reader_proxy_data()
→ SEDP Writer 发送 DATA(w)/DATA(r)
5.4 消息发送与接收流程

发送路径(Writer → 网络)
用户调用 DataWriter::write()
│
▼
WriterHistory::add_change() # 创建 CacheChange_t,分配序列号
│
▼
BaseWriter::unsent_change_added_to_history() # 通知 Writer 有未发送变更
│
├─► [异步模式] FlowController::add_new_sample()
│ └─► FlowControllerImpl 调度 → deliver_sample_nts()
│
└─► [同步模式] 直接调用 deliver_sample_nts()
│
▼
StatefulWriter::deliver_sample_nts()
│
├─► 遍历 matched_readers_(ReaderProxy 列表)
│ │
│ ├─► 检查 Reader 是否需要此变更(reader_data_filter_)
│ ├─► intraprocess_delivery() → 同进程直达 Reader
│ │
│ └─► [网络发送] RTPSMessageGroup::add_data()
│ │
│ ▼
│ RTPSMessageCreator::addSubmessageData() # 序列化 DATA 子消息
│ │
│ ▼
│ RTPSMessageGroup(缓冲区管理,打包多个子消息)
│ │
│ ├─► addHeader() 添加 RTPS 头部
│ ├─► 累积子消息直到缓冲区满或 flush()
│ │
│ ▼
│ RTPSMessageGroup::flush() → LocatorSelectorSender::send()
│ │
│ ▼
│ RTPSParticipantImpl::sendSync()
│ │
│ └─► 遍历 send_resource_list_ → SenderResource::send()
│ │
│ ▼
│ TransportInterface(UDP/TCP/SHM)→ 网络
│
└─► [RELIABLE] 周期性 Heartbeat → ACKNACK 确认
接收路径(网络 → Reader)
网络数据到达 → ReceiverResource 回调
│
▼
MessageReceiver::processCDRMsg()
│
├─► 解析 RTPS Header(GUID Prefix, Protocol Version, VendorId)
├─► 遍历所有 Submessage:
│ ├─► DATA / DATA_FRAG → 路由到目标 Reader → process_data_msg()
│ ├─► HEARTBEAT → 路由到目标 Reader → process_heartbeat_msg() → send_acknack()
│ ├─► ACKNACK → 路由到目标 Writer → process_acknack()
│ ├─► GAP → 路由到目标 Reader → process_gap_msg()
│ └─► INFO_TS / INFO_SRC / INFO_DST(元信息)
│
└─► DATA(p)/DATA(w)/DATA(r) → 路由到 BuiltinProtocols → PDP/EDP 处理
5.5 关键设计要点
-
ReaderProxy / WriterProxy :StatefulWriter 为每个匹配的 Reader 维护
ReaderProxy(含 ACKNACK 状态、未发送变更列表);StatefulReader 为每个匹配的 Writer 维护WriterProxy(含序列号跟踪)。 -
FlowController:异步发布模式下,变更先加入 FlowController 队列,由专用线程调度发送,实现带宽限制和流量整形。
-
RTPSMessageGroup:将多个子消息打包成一个 RTPS 报文,减少网络开销。
-
Intraprocess 优化 :同一进程内的 Writer-Reader 对跳过序列化和网络发送,直接传递
CacheChange_t指针。 -
DataSharing :通过共享内存段实现零拷贝数据传输,由
DataSharingPool和DataSharingListener/Notifier管理。
六、传输层(Transport Layer)
传输层负责实际的数据发送和接收,支持多种传输协议。
传输类层次
TransportInterface(抽象基类)
├── UDPTransportInterface
│ ├── UDPv4Transport
│ └── UDPv6Transport
├── TCPTransportInterface
│ ├── TCPv4Transport
│ └── TCPv6Transport
├── SharedMemTransport # 共享内存传输
├── ChainingTransport # 链式适配器(可用于传输层叠加)
└── MulticastTransportInterface # 多播传输接口
各传输方式特点
| 传输方式 | 适用场景 | 特点 |
|---|---|---|
| UDP | 同机 / 局域网 | 低延迟、支持多播、无连接 |
| TCP | 跨网络 / 广域网 | 可靠传输、面向连接、支持 TLS 加密 |
| Shared Memory (SHM) | 同机进程间 | 零拷贝、极低延迟、高吞吐 |
SHM 传输原理
SHM 传输基于 MultiProducerConsumerRingBuffer(多生产者-消费者环形缓冲区),通过以下组件协作:
SharedMemManager--- 管理共享内存段和端口SharedMemGlobal--- 全局资源(端口 + 环形缓冲)SharedMemTransport--- 传输实现SHMLocator--- 共享内存定位器
传输注册机制
NetworkFactory
├── 注册 TransportDescriptor → 创建 TransportInterface 实例
├── 构建 SenderResource 列表(发送通道)
├── 构建 ReceiverResource 列表(接收通道)
└── 根据 Locator 自动选择合适的传输
七、安全模块(DDS Security)
安全模块遵循 DDS Security 规范 1.1,采用三层插件架构:
┌─────────────────────────────┐
│ Authentication(认证) │ ← PKI + DH 密钥交换
├─────────────────────────────┤
│ AccessControl(访问控制) │ ← Governance + Permissions XML
├─────────────────────────────┤
│ Cryptography(加密) │ ← AES-GCM-GMAC
│ ├── CryptoTransform │ 消息加解密
│ ├── CryptoKeyExchange │ 密钥交换
│ └── CryptoKeyFactory │ 密钥工厂
└─────────────────────────────┘
| 层 | 实现类 | 功能 |
|---|---|---|
| Authentication | PKIDH (91KB) |
验证本地/远程身份,Diffie-Hellman 密钥交换 |
| AccessControl | Permissions |
解析权限文件,检查创建/读写权限 |
| Cryptography | AESGCMGMAC_* |
AES-GCM-GMAC 加解密 RTPS 子消息和 Payload |
八、其他重要模块
8.1 流控制(FlowController)
FlowController(抽象接口)
├── FlowControllerImpl # 标准实现
├── FlowControllerFactory # 工厂,管理多个 FlowController 实例
└── FlowControllerSchedulerPolicy # 调度策略
- 异步模式下,数据变更先入队,由 FlowController 按策略调度发送
- 支持带宽限制、优先级调度等
8.2 历史缓存(History)
WriterHistory # 写入者历史
├── CacheChange_t 池管理
├── 序列号分配
└── 变更生命周期管理
ReaderHistory # 读取者历史
├── 接收的变更存储
└── 序列号排序和去重
CacheChange_t是数据的核心载体,包含序列号、Payload、时间戳CacheChangePool提供预分配的对象池,避免动态内存分配
8.3 持久化(Persistence)
PersistenceService--- 持久化服务接口SQLite3PersistenceService--- 基于 SQLite3 的实现PersistentWriter/Reader--- 支持持久化的 Writer/Reader 变体- 用于保证重启后数据不丢失
8.4 统计与监控(Statistics)
MonitorService--- 监控服务核心- 提供
IConnectionsObserver,IProxyObserver,IStatusObserver等接口 - 可查询和监控实体状态、连接信息、QoS 指标
8.5 X-Types 动态类型
DynamicData(45KB) --- 运行时动态数据类型DynamicType--- 动态类型定义TypeObjectUtils(137KB) --- TypeObject 序列化/匹配工具TypeLookupService--- 类型查询服务,实现类型自动传播
8.6 RPC(Request-Reply)
Requester/Replier--- 基于 DDS 的 RPC 模式Service--- 服务定义- 通过 Request/Reply Topic 实现请求-回复语义
九、系列文章规划
基于以上模块分析,建议后续专题文章安排如下:
| 序号 | 主题 | 内容概要 |
|---|---|---|
| (一) | 架构总览与模块介绍 ← 本文 | |
| (二) | DDS 层核心实体 | DomainParticipant/Publisher/Subscriber/DataWriter/DataReader 的创建与生命周期 |
| (三) | RTPS Writer 深度剖析 | StatefulWriter vs StatelessWriter,ReaderProxy,可靠传输机制 |
| (四) | RTPS Reader 深度剖析 | StatefulReader vs StatelessReader,WriterProxy,ACKNACK 生成 |
| (五) | 发现协议(上):PDP | SimplePDP/Discovery Server,参与者宣告与发现 |
| (六) | 发现协议(下):EDP | SimpleEDP/StaticEDP,端点匹配与 QoS 兼容性检查 |
| (七) | 消息系统 | RTPSMessageGroup/RTPSMessageCreator,子消息构造与解析 |
| (八) | 传输层详解 | UDP/TCP/SHM 传输实现,通道管理 |
| (九) | QoS 策略实现 | RELIABILITY/DUARABILITY/DEADLINE 等策略的内部实现 |
| (十) | 内存管理 | CacheChangePool、foonathan_memory 集成、零拷贝 |
| (十一) | 安全模块 | 认证、访问控制、加密三层插件架构 |
| (十二) | 高级特性 | X-Types/RPC/Statistics/FlowController/Persistence |
十、阅读源码的建议
- 从示例入手 :
examples/cpp/下有 13 个示例,从HelloWorldExample开始 - 跟踪 write() 调用链 :从
DataWriter::write()一路追到网络发送,这是理解核心流程的最佳路径 - 关注 Impl 类 :公共 API 类大多是外观,真正的逻辑在
*Impl类中 - 先理解 RTPS 层再回看 DDS 层:DDS 层本质上是对 RTPS 层的封装
- 善用 DDS 规范:OMG DDS 和 RTPS 规范是理解设计的权威参考
下一篇预告:DDS 层核心实体 --- DomainParticipant 的创建、QoS 转换与实体生命周期管理。