当前位置: 首页 > article >正文

RTPS通信使用的socket和端口

RTPS通信使用的socket和端口

概述

​ 在FastRTPS中,无论SenderResource还是,ReceiverResource,其内部会依赖NetworkFactory创建socket,每个socket都需要绑定socket才能正常使用。

​ 一般来说,一个RTPSParticipant中创建的RTPSReader/RTPSWriter都是共用一组socket资源的,而这些socket的端口的值一般是RTPSParticipant的domainid和participantid相关的。

​ 上层应用可以指定创建的RTPSParticipant用于元数据和业务数据通信的单播地址/组播地址,但是无法指定通信的端口,端口是RTPS中根据规则进行计算分配的。

​ 下面主要是梳理一下一个RTPSParticipant会创建哪些socket,每一类socket绑定的端口规则是怎样的。

创建的socket

​ 通过阅读RTPSReader,RTPSWriter,StatelessWriter,StatelessReader,StatefulWriter以及StatefulReader的代码可以发现,这些endpoint类是只负责处理数据,管理匹配的对端endpoint,而发送和接收数据都是依赖内部的history对象的。history中的数据则是依赖了下层的ReceiverResource和SenderResource,而ReceiverResource和SenderResource是依赖了更下层Transport中的各种ChannelResource来进行网络数据通信的,每个ChannelResource中包含了用于地层数据通信的socket对象

发送

​ 发送的Socket在SenderResource中创建,有如下几个创建的时机点

​ 1. 创建RTPSParticipant设置qos的时候

DomainParticipantImpl::set_qos
	RTPSParticipant::update_attributes
		RTPSParticipantImpl::update_attributes
			createSenderResources(元数据组播地址)
			createSenderResources(元数据单播地址)
			createSenderResources(业务数据单播地址)
				NetworkFactory::build_send_resources
					UDPTransportInterface::OpenOutputChannel
					UDPTransportInterface::OpenAndBindUnicastOutputSocket
					UDPTransportInterface::createUDPSocket
				

​ 2. StatelessWriter匹配到对端Reader

StatelessWriter::matched_reader_add
	StatelessWriter::update_reader_info
		RTPSParticipantImpl::createSenderResources

​ 3. StatefulWriter匹配到对端Reader

StatefulWriter::matched_reader_add
	StatefulWriter::update_reader_info
		RTPSParticipantImpl::createSenderResources

​ 4. StatefulReader匹配到对端Writer(需要创建SenderResource用于发送ACKNACK消息)

StatefulReader::matched_writer_add
	RTPSParticipantImpl::createSenderResources

接收

​ 接收的Socket在ReceiverResource中创建,

元数据组播地址绑定的端口

​ https://gitee.com/zzl0109/Fast-DDS/blob/master/include/fastdds/rtps/common/PortParameters.h

    inline uint32_t getMulticastPort(
            uint32_t domainId) const
    {
        uint32_t port = portBase + domainIDGain * domainId + offsetd0;
		...
		return port;
	}

元数据单播地址绑定的端口

​ https://gitee.com/zzl0109/Fast-DDS/blob/master/include/fastdds/rtps/common/PortParameters.h

inline uint32_t getUnicastPort(
            uint32_t domainId,
            uint32_t RTPSParticipantID) const
    {
        uint32_t port = portBase + domainIDGain * domainId + offsetd1   + participantIDGain * RTPSParticipantID;
		...
		return port;
	}

业务数据单播地址绑定端口

​ https://gitee.com/zzl0109/Fast-DDS/blob/master/src/cpp/rtps/participant/RTPSParticipantImpl.cpp

...
RTPSParticipantImpl::RTPSParticipantImpl(
	...
    // 上层应用未指定单播和组播地址
    if (m_att.defaultUnicastLocatorList.empty() && m_att.defaultMulticastLocatorList.empty())
    {
        get_default_unicast_locators();
        internal_default_locators_ = true;
		        EPROSIMA_LOG_INFO(RTPS_PARTICIPANT,
                m_att.getName() << " Created with NO default Unicast Locator List, adding Locators:"
                                << m_att.defaultUnicastLocatorList);
    }
	else
    {
        // Locator with port 0, calculate port.  指定了地址,通过计算分配端口
        std::for_each(m_att.defaultUnicastLocatorList.begin(), m_att.defaultUnicastLocatorList.end(),
                [&](Locator_t& loc)
                {   // 端口通过calculate_well_known_port计算
                    m_network_Factory.fill_default_locator_port(domain_id_, loc, m_att, false);
                });
        m_network_Factory.NormalizeLocators(m_att.defaultUnicastLocatorList);

        std::for_each(m_att.defaultMulticastLocatorList.begin(), m_att.defaultMulticastLocatorList.end(),
                [&](Locator_t& loc)
                {   // 端口通过calculate_well_known_port计算
                    m_network_Factory.fill_default_locator_port(domain_id_, loc, m_att, true);
                });
    }
	...
}

...

void RTPSParticipantImpl::get_default_unicast_locators()
{
    m_network_Factory.getDefaultUnicastLocators(domain_id_, m_att.defaultUnicastLocatorList, m_att);
    m_network_Factory.NormalizeLocators(m_att.defaultUnicastLocatorList);
}

...

​ https://gitee.com/zzl0109/Fast-DDS/blob/master/src/cpp/rtps/network/NetworkFactory.cpp

bool NetworkFactory::getDefaultUnicastLocators(
        uint32_t domain_id,
        LocatorList_t& locators,
        const RTPSParticipantAttributes& m_att) const
{
    bool result = false;
    for (auto& transport : mRegisteredTransports)
    {
        result |= transport->getDefaultUnicastLocators(locators, calculate_well_known_port(domain_id, m_att, false));
    }
    return result;
}

bool NetworkFactory::fill_default_locator_port(
        uint32_t domain_id,
        Locator_t& locator,
        const RTPSParticipantAttributes& m_att,
        bool is_multicast) const
{
    bool result = false;
    for (auto& transport : mRegisteredTransports)
    {
        if (transport->IsLocatorSupported(locator))
        {   // 端口通过calculate_well_known_port计算
            result |= transport->fillUnicastLocator(locator, calculate_well_known_port(domain_id, m_att, is_multicast));
        }
    }
    return result;
}

uint16_t NetworkFactory::calculate_well_known_port(
        uint32_t domain_id,
        const RTPSParticipantAttributes& att,
        bool is_multicast) const
{

    uint32_t port = att.port.portBase +
            att.port.domainIDGain * domain_id +
            (is_multicast ?
            att.port.offsetd2 :
            att.port.offsetd3 + att.port.participantIDGain * att.participantID);

    if (port > 65535)
    {
       	...  // error log
        exit(EXIT_FAILURE);
    }

    return static_cast<uint16_t>(port);
}

业务数据组播地址绑定端口

发送业务数据使用的端口


http://www.kler.cn/a/405320.html

相关文章:

  • uniapp input限制输入负数,以及保留小数点两位.
  • Swift从0开始学习 协议和扩展 day5
  • 友思特新闻 | 友思特荣获广州科技创新创业大赛智能装备行业赛初创组优胜企业!
  • 音频信号采集前端电路分析
  • 一次需升级系统的wxpython安装(macOS M1)
  • Docker Compose安装部署PostgreSQL数据库
  • 从零开始:如何使用第三方视频美颜SDK开发实时直播美颜平台
  • 在 Swift 中实现字符串分割问题:以字典中的单词构造句子
  • 摸一下elasticsearch8的AI能力:语义搜索/vector向量搜索案例
  • GPU服务器厂家:为什么要选择 GPU 服务器?
  • 包装器与绑定器
  • 06、Spring AOP
  • Bug Fix 20241122:缺少lib文件错误
  • 低速接口项目之串口Uart开发(四)——UART串口实现FPGA内部AXILITE寄存器的读写控制
  • 历遍单片机下的IIC设备[ESP--0]
  • 浅谈新能源光储充一体化电站设计方案
  • PyTorch图像预处理:计算均值和方差以实现标准化
  • 网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
  • RocketMQ文件刷盘机制深度解析与Java模拟实现
  • Leecode刷题C语言之统计不是特殊数字的数字数量
  • xbh的比赛
  • Qt 的事件投递机制:从基础到实战
  • 动态调试对安全研究有什么帮助?
  • 设计模式之 模板方法模式
  • vue中路由缓存
  • Python创建虚拟环境报错:Error: Command......