FastDDS跨网段通信全解析:方法对比、云端部署与实战配置
在工业物联网、智能机器人协同、车载设备互联等场景中,设备常跨网段(甚至跨公网)部署,数据的实时、可靠传输成为核心需求。FastDDS(基于DDS标准的开源实现)作为工业级实时通信协议,凭借低延迟、高吞吐量、丰富QoS能力,成为跨网段通信的优选方案。本文将从「跨网段通信方法选型」切入,详细讲解云端服务器FastDDS环境部署、Discovery Server配置、本地/远端发布订阅参数配置,最后通过
文章目录
FastDDS跨网段通信全解析:方法对比、云端部署与实战配置
在工业物联网、智能机器人协同、车载设备互联等场景中,设备常跨网段(甚至跨公网)部署,数据的实时、可靠传输成为核心需求。FastDDS(基于DDS标准的开源实现)作为工业级实时通信协议,凭借低延迟、高吞吐量、丰富QoS能力,成为跨网段通信的优选方案。
本文将从「跨网段通信方法选型」切入,详细讲解云端服务器FastDDS环境部署、Discovery Server配置、本地/远端发布订阅参数配置,最后通过实战案例验证通信效果,帮你快速搞定FastDDS跨网段落地。
一、FastDDS跨网段通信常用方法对比
跨网段场景下,FastDDS主流通信方案有4种,需根据实时性、部署成本、设备资源选型,以下是核心对比(附适用场景):
| 通信方案 | 核心原理 | 实时性 | 部署复杂度 | 运维成本 | 适用场景 |
|---|---|---|---|---|---|
| Discovery Server(原生方案) | 部署中心DS节点,跨网段设备通过DS完成节点发现,数据P2P直连 | 高(微秒-毫秒级) | 中(需配置DS+端口放行) | 低(仅维护DS节点) | 工业控制、机器人协同、高频数据传输 |
| MQTT转发方案 | 放弃FastDDS原生发现,通过MQTT Broker转发数据(FastDDS→MQTT协议转换) | 中(毫秒-秒级) | 低(部署MQTT Broker即可) | 中(维护Broker+协议转换网关) | 低资源设备、跨生态通信、轻量监控 |
| FastDDS+MQTT混合架构 | 同网段用FastDDS保证实时性,跨网段通过MQTT网关转发数据 | 中高(本地实时+跨网段低延迟) | 高(维护DS+Broker+网关) | 中高(多组件协同) | 本地集群+跨厂区通信、混合设备场景 |
| VPN专线方案 | 通过VPN将跨网段设备接入同一虚拟局域网,FastDDS按局域网方式通信 | 高(接近局域网性能) | 高(部署VPN服务器+设备接入) | 高(VPN带宽+运维) | 高安全需求、对实时性要求极高的场景 |
| 选型结论:若无需跨生态、追求实时性,优先选「Discovery Server原生方案」(本文重点讲解);若设备资源有限、需快速上线,可选「MQTT转发方案」;安全优先则考虑VPN专线。 |
二、云端服务器FastDDS环境部署(以阿里云/腾讯云为例)
跨网段通信的核心是部署「云端Discovery Server(DS)」,作为跨网段设备的发现中心。以下步骤基于 Ubuntu 20.04 系统(CentOS 操作类似),云服务器IP以 00.00.00.00 为例。
2.1 环境依赖安装
FastDDS依赖C++11及以上、CMake、Boost等工具,执行以下命令安装:
# 更新软件源
sudo apt update && sudo apt upgrade -y
# 安装基础依赖
sudo apt install -y build-essential cmake git libboost-all-dev libssl-dev
# 安装Python依赖(用于FastDDS工具)
sudo apt install -y python3-pip python3-colcon-common-extensions
2.2 FastDDS编译安装(最新稳定版2.12.0)
FastDDS推荐源码编译安装,确保功能完整:
# 克隆源码(指定稳定版)
git clone -b 2.12.0 https://github.com/eProsima/Fast-DDS.git
cd Fast-DDS
mkdir build && cd build
# 编译配置(默认安装到/usr/local)
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
# 编译安装(-j后面跟CPU核心数,加速编译)
make -j4
sudo make install
# 验证安装(查看版本)
fastdds --version
若输出 eProsima Fast DDS x.x.x ,说明安装成功。
2.3 云服务器网络配置(关键!)
跨网段通信需放行FastDDS核心端口,云服务器需配置「操作系统防火墙」和「云平台安全组」:
2.3.1 操作系统防火墙放行端口
# 放行DS发现端口(默认11811,TCP/UDP)
sudo firewall-cmd --add-port=11811/tcp --permanent
sudo firewall-cmd --add-port=11811/udp --permanent
# 放行用户数据端口(默认7400,TCP/UDP)
sudo firewall-cmd --add-port=7400/tcp --permanent
sudo firewall-cmd --add-port=7400/udp --permanent
# 重载防火墙规则
sudo firewall-cmd --reload
# 验证端口放行
sudo firewall-cmd --list-ports
2.3.2 云平台安全组配置
登录阿里云/腾讯云控制台,找到对应服务器的「安全组」→「入站规则」,添加两条规则:
-
规则1:端口范围
11811,协议 TCP/UDP,源地址0.0.0.0/0(测试用,生产环境可限定客户端网段) -
规则2:端口范围
7400,协议 TCP/UDP,源地址0.0.0.0/0
⚠️ 注意:安全组配置是跨公网通信的关键,若未配置,客户端会无法连接DS服务器。
三、云端Discovery Server配置与服务启动
DS服务器需配置「禁用多播」「绑定公网IP」「指定端口」,避免配置冲突。
3.1 编写DS配置文件(ds_server_public.xml)
在云服务器上创建配置文件,路径建议 /home/ubuntu/fastdds_config/ds_server_public.xml,内容如下(关键参数有注释):
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///usr/local/share/fastdds/schema/fastdds.xsd">
<profiles>
<!-- 云端DS节点配置,默认配置文件 -->
<participant profile_name="PublicDiscoveryServer" is_default_profile="true">
<rtps>
<!-- 公网MTU配置(避免IP分片) -->
<mtu>1472</mtu>
<builtin>
<discovery_config>
<!-- 禁用多播(跨网段多播会被路由阻断) -->
<multicast_enabled>false</multicast_enabled>
<!-- 清空静态对等节点(仅用DS发现) -->
<initial_peers_list clear="true"/>
</discovery_config>
<!-- DS核心配置 -->
<discovery_server>
<enabled>true</enabled>
<server_id>0</server_id> <!-- 服务器固定ID为0(超级节点) -->
<server_addresses>
<locator>
<tcpv4> <!-- 公网优先用TCP,穿透性更强、丢包更少 -->
<address>00.00.00.00</address> <!-- 云服务器公网IP -->
<port>11811</port><!-- DS默认端口 -->
</tcpv4>
</locator>
</server_addresses>
</discovery_server>
</builtin>
<!-- 传输层配置(仅保留TCP,跨网段无需共享内存SHM) -->
<transports>
<transport_id>tcp_transport</transport_id>
<type>TCPv4</type>
<tcpv4>
<nagle_algorithm>false</nagle_algorithm> <!-- 禁用Nagle算法,减少小包延迟 -->
<keep_alive>true</keep_alive><!-- 开启TCP保活,避免公网连接断开 -->
</tcpv4>
</transports>
<!-- 指定传输优先级(仅用TCP) -->
<userTransports>
<transport_id>tcp_transport</transport_id>
</userTransports>
<!-- 用户数据传输端口 -->
<default_unicast_port>7400</default_unicast_port>
</rtps>
</participant>
</profiles>
</dds>
3.2 启动DS服务(后台常驻)
使用FastDDS自带工具启动DS,建议后台运行(避免终端关闭后进程退出):
# 后台启动DS,日志输出到ds_log.log
nohup fastdds discovery -i 0 -c /home/ubuntu/fastdds_config/ds_server_public.xml > /home/ubuntu/fastdds_config/ds_log.log 2>&1 &
# 验证DS进程是否运行
ps -ef | grep fastdds
# 验证端口是否监听
netstat -tulpn | grep 11811
若输出类似 tcp 0 0 00.00.00.00:11811 0.0.0.0:* LISTEN 12345/fastdds ,说明DS服务已正常启动并监听端口。
四、本地/远端程序配置(发布者/订阅者)
跨网段的客户端(本地电脑/远端设备)需配置「指向云端DS服务器」「禁用多播」「适配TCP传输」,发布者和订阅者配置类似,仅QoS可按需调整。
4.1 客户端通用配置文件(client_config.xml)
在本地/远端客户端创建配置文件,路径建议 ./fastdds_config/client_config.xml,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///usr/local/share/fastdds/schema/fastdds.xsd">
<profiles>
<!-- 客户端域参与者配置(发布者/订阅者共用) -->
<participant profile_name="CrossNetworkClient" is_default_profile="true">
<rtps>
<mtu>1472</mtu>
<builtin>
<discovery_config>
<multicast_enabled>false</multicast_enabled>
<initial_peers_list clear="true"/>
</discovery_config>
<!-- 客户端DS配置,指向云端服务器 -->
<discovery_server>
<enabled>true</enabled>
<server_id>1</server_id> <!-- 客户端ID必须非0,不同客户端可设为1、2、3... -->
<server_addresses>
<locator>
<tcpv4>
<address>00.00.00.00</address> <!-- 云端DS公网IP -->
<port>11811</port> <!-- 与DS端口一致 -->
</tcpv4>
</locator>
</server_addresses>
</discovery_server>
<!-- 客户端DS超时配置(适配公网延迟) -->
<discovery_server_client>
<leaseDuration><sec>60</sec></leaseDuration> <!-- 租期60秒 -->
<leaseRenewal><sec>20</sec></leaseRenewal> <!-- 提前20秒续租 -->
<connection_timeout><sec>5</sec></connection_timeout> <!-- 连接超时5秒 -->
</discovery_server_client>
</builtin>
<!-- 传输层配置(与DS一致,用TCP) -->
<transports>
<transport_id>tcp_transport</transport_id>
<type>TCPv4</type>
<tcpv4>
<nagle_algorithm>false</nagle_algorithm>
<keep_alive>true</keep_alive>
</tcpv4>
</transports>
<userTransports>
<transport_id>tcp_transport</transport_id>
</userTransports>
<default_unicast_port>7400</default_unicast_port>
</rtps>
</participant>
<!-- 发布者QoS配置(按需调整) -->
<publisher profile_name="CrossNetworkPublisher" is_default_profile="true">
<qos>
<reliability><kind>RELIABLE_RELIABILITY_QOS</kind></reliability> <!-- 可靠传输 -->
<durability><kind>VOLATILE_DURABILITY_QOS</kind></durability> <!-- 无缓存,即时传输 -->
</qos>
</publisher>
<!-- 订阅者QoS配置(与发布者一致,保证匹配) -->
<subscriber profile_name="CrossNetworkSubscriber" is_default_profile="true">
<qos>
<reliability><kind>RELIABLE_RELIABILITY_QOS</kind></reliability>
<durability><kind>VOLATILE_DURABILITY_QOS</kind></durability>
</qos>
</subscriber>
<!-- 数据写入者(发布者)配置 -->
<data_writer profile_name="CrossNetworkDataWriter" is_default_profile="true">
<qos>
<history>
<kind>KEEP_LAST_HISTORY_QOS</kind>
<depth>1</depth> <!-- 仅保留最新1条数据,减少延迟 -->
</history>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
<max_blocking_time><nanosec>50000000</nanosec></max_blocking_time> <!-- 阻塞上限50ms -->
</reliability>
</qos>
</data_writer>
<!-- 数据读取者(订阅者)配置 -->
<data_reader profile_name="CrossNetworkDataReader" is_default_profile="true">
<qos>
<history><kind>KEEP_LAST_HISTORY_QOS</kind><depth>1</depth></history>
<reliability><kind>RELIABLE_RELIABILITY_QOS</kind></reliability>
</qos>
</data_reader>
</profiles>
</dds>
4.2 发布者/订阅者程序开发(C++示例)
FastDDS程序需包含「类型定义」「域参与者创建」「发布/订阅初始化」,核心是加载上述配置文件。以下是简化示例(假设自定义消息类型为 HelloWorld):
4.2.1 发布者程序(publisher.cpp)
#include "HelloWorldPubSubTypes.h"
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/data_writer/DataWriter.hpp>
using namespace eprosima::fastdds::dds;
int main()
{
// 1. 加载配置文件(关键:指定客户端配置)
DomainParticipantFactory::get_instance()->load_XML_profiles("fastdds_config/client_config.xml");
// 2. 创建域参与者(使用默认配置)
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (participant == nullptr) return -1;
// 3. 注册消息类型
HelloWorldPubSubType type;
participant->register_type(&type);
// 4. 创建主题(主题名需与订阅者一致)
Topic* topic = participant->create_topic("HelloWorldTopic", type.get_type_name(), TOPIC_QOS_DEFAULT);
if (topic == nullptr) return -1;
// 5. 创建发布者
Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (publisher == nullptr) return -1;
// 6. 创建数据写入者
DataWriter* writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (writer == nullptr) return -1;
// 7. 循环发布数据
HelloWorld msg;
int count = 0;
while (true)
{
msg.message("Hello FastDDS Cross Network! Count: " + std::to_string(count++));
writer->write(&msg);
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 每秒发布一次
}
// 8. 资源释放(实际项目中需处理退出逻辑)
participant->delete_publisher(publisher);
participant->delete_topic(topic);
DomainParticipantFactory::get_instance()->delete_participant(participant);
return 0;
}
4.2.2 订阅者程序(subscriber.cpp)
#include "HelloWorldPubSubTypes.h"
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/data_reader/DataReader.hpp>
#include <fastdds/dds/data_reader/DataReaderListener.hpp>
using namespace eprosima::fastdds::dds;
// 监听类:处理接收的数据
class SubListener : public DataReaderListener
{
public:
void on_data_available(DataReader* reader) override
{
HelloWorld msg;
SampleInfo info;
if (reader->take_next_sample(&msg, &info) == ReturnCode_t::RETCODE_OK && info.valid_data)
{
std::cout << "Received message: " << msg.message() << std::endl;
}
}
};
int main()
{
// 1. 加载配置文件
DomainParticipantFactory::get_instance()->load_XML_profiles("fastdds_config/client_config.xml");
// 2. 创建域参与者
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (participant == nullptr) return -1;
// 3. 注册消息类型
HelloWorldPubSubType type;
participant->register_type(&type);
// 4. 创建主题(与发布者主题名一致)
Topic* topic = participant->create_topic("HelloWorldTopic", type.get_type_name(), TOPIC_QOS_DEFAULT);
if (topic == nullptr) return -1;
// 5. 创建订阅者
Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (subscriber == nullptr) return -1;
// 6. 创建数据读取者(绑定监听)
SubListener listener;
DataReader* reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT, &listener);
if (reader == nullptr) return -1;
// 7. 阻塞等待数据
std::cout << "Subscriber waiting for data..." << std::endl;
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
// 8. 资源释放
participant->delete_subscriber(subscriber);
participant->delete_topic(topic);
DomainParticipantFactory::get_instance()->delete_participant(participant);
return 0;
}
4.3 编译运行(CMakeLists.txt简化配置)
cmake_minimum_required(VERSION 3.10)
project(FastDDS_Cross_Network)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找FastDDS依赖
find_package(fastcdr REQUIRED)
find_package(fastrtps REQUIRED)
# 生成消息类型文件(HelloWorld.idl编译生成)
add_custom_command(
OUTPUT HelloWorldPubSubTypes.cpp HelloWorldPubSubTypes.h
COMMAND fastddsgen -cs -cpp HelloWorld.idl
DEPENDS HelloWorld.idl
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
# 发布者可执行文件
add_executable(publisher publisher.cpp HelloWorldPubSubTypes.cpp)
target_link_libraries(publisher fastrtps fastcdr)
# 订阅者可执行文件
add_executable(subscriber subscriber.cpp HelloWorldPubSubTypes.cpp)
target_link_libraries(subscriber fastrtps fastcdr)
编译运行命令:
# 创建build目录
mkdir build && cd build
# 编译
cmake .. && make -j4
# 运行订阅者(本地/远端设备)
./subscriber
# 运行发布者(另一台跨网段设备)
./publisher
五、实战测试与问题排查
5.1 正常通信现象
-
订阅者终端输出:
Subscriber waiting for data...后,陆续收到Received message: Hello FastDDS Cross Network! Count: 0,1,2... -
云端DS日志(ds_log.log)无报错,出现
Client connected相关日志
5.2 常见问题排查
问题1:客户端无法连接DS服务器
排查步骤:
-
ping 00.00.00.00验证公网可达
-
telnet 00.00.00.00 11811 验证端口是否通(通则返回 Connected)
-
检查云服务器安全组是否放行11811端口
-
检查DS配置文件中 address 是否为云服务器公网IP(而非内网IP/127.0.0.1)
问题2:能连接DS,但收不到数据
排查步骤:
-
确认发布者/订阅者主题名一致(本文为 HelloWorldTopic)
-
确认QoS匹配(可靠性、持久性策略一致)
-
检查客户端配置文件中 transport 与DS一致(均为TCP)
-
用 fastdds monitor 工具可视化查看节点是否正常发现
问题3:公网通信卡顿/丢包
解决方案:
-
增大客户端 leaseDuration 租期(如改为120秒)
-
调整可靠性策略的 max_retry_count(最多3次重传)
-
启用数据压缩(参考前文实时性优化配置)
六、总结与优化建议
FastDDS跨网段通信的核心是「Discovery Server+TCP传输」,其优势在于实时性和可靠性,适合工业级场景。本文通过“云端DS部署→客户端配置→实战测试”的完整流程,帮你快速落地跨网段通信。
进阶优化建议:
-
传输层:若公网延迟低、丢包少,可改用 UDP-Lite 进一步降低延迟
-
QoS:实时性优先场景,将可靠性策略改为 BEST_EFFORT_RELIABILITY_QOS(无重传)
-
监控:用 FastDDS Monitor 工具实时监控延迟、丢包率,动态调整配置
-
安全:公网场景可启用 FastDDS 加密功能(配置 TLS/SSL),防止数据泄露
通过本文配置,FastDDS跨公网端到端延迟可控制在50-100ms,满足大多数工业实时通信需求。如果需要更极致的实时性,可考虑云服务器就近部署或专线网络。
(注:文档部分内容可能由 AI 生成)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)