You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在RTI DDS 5.2.3.17中获取DataWriter/Publisher的IP地址?

Getting the IP Address of an RTI DDS 5.2.3.17 DataWriter/Publisher for Logging

Hey there! I’ve worked with RTI DDS 5.x quite a bit, so let’s walk through how to grab the IP address tied to your DataWriter/Publisher and log it properly. The key thing to remember here is that DataWriters and Publishers don’t directly hold IP info—they rely on the DomainParticipant’s transport configuration. Here’s how to extract it:

Step 1: Trace Back to the DomainParticipant

First, you need to get from your DataWriter up to the DomainParticipant, since that’s where transport settings are managed:

// Assuming you already have your DataWriter instance
DDS::DataWriter* dw = your_data_writer;
DDS::Publisher* pub = dw->get_publisher();
DDS::DomainParticipant* participant = pub->get_participant();

Step 2: Use RTI’s Extended API to Get Transport Info

Standard DDS doesn’t expose transport-level details, so you’ll need to use RTI’s proprietary extensions. For UDPv4 (the most common transport), here’s how to pull the local IP:

C++ Example

#include <rti/dds/domain/DomainParticipant.hpp>
#include <rti/transport/UdpTransport.hpp>
#include <iostream>

// ... (previous code to get participant)

// Fetch the transport configuration from the participant
auto transport_config = participant->get_transport_configuration();
for (const auto& transport : transport_config.transports()) {
    // Filter for UDPv4 transports (skip shared memory if present)
    if (transport->kind() == RTI::DDS::TransportKind::UDPv4) {
        auto udp_transport = dynamic_cast<RTI::DDS::UdpTransport*>(transport.get());
        if (udp_transport != nullptr) {
            // Get all local addresses the transport is bound to
            auto local_addresses = udp_transport->local_addresses();
            for (const auto& addr : local_addresses) {
                std::string ip = addr.to_string();
                // Log this IP—replace with your logging call
                std::cout << "DataWriter/Publisher IP: " << ip << std::endl;
            }
        }
    }
}

C Example (if you’re using the C API)

#include <dds/domain/DomainParticipant.h>
#include <rti/transport/TransportInfo.h>
#include <stdio.h>

// ... (previous code to get participant)

RTI_DDS_TransportInfoSeq transport_info_seq;
RTI_DDS_TransportInfoSeq_initialize(&transport_info_seq);

// Fetch transport info
DDS_ReturnCode_t ret = RTI_DDS_DomainParticipant_GetCurrentTransportInfo(
    participant, &transport_info_seq);

if (ret == DDS_RETCODE_OK) {
    for (int i = 0; i < RTI_DDS_TransportInfoSeq_get_length(&transport_info_seq); i++) {
        RTI_DDS_TransportInfo* info = RTI_DDS_TransportInfoSeq_get(&transport_info_seq, i);
        // Check for UDPv4 transport
        if (info->transport_kind == RTI_DDS_TRANSPORT_KIND_UDPv4) {
            char ip_str[256];
            // Convert network address to string
            RTI_DDS_String_from_network_address(ip_str, sizeof(ip_str), &info->local_address);
            printf("Associated IP: %s\n", ip_str);
        }
    }
}

// Clean up
RTI_DDS_TransportInfoSeq_finalize(&transport_info_seq);

Step 3: Handle the "0.0.0.0" Case

If your DomainParticipant is bound to 0.0.0.0 (listening on all interfaces), the above code will return that instead of a specific IP. To get the actual physical IP your app is using, you’ll need to use system-specific APIs to fetch the machine’s non-loopback IP:

Linux C++ Example

#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>

std::string get_physical_local_ip() {
    struct ifaddrs *ifap, *ifa;
    struct sockaddr_in *sa;
    std::string ip;

    getifaddrs(&ifap);
    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
            sa = (struct sockaddr_in *) ifa->ifa_addr;
            std::string current_ip = inet_ntoa(sa->sin_addr);
            // Skip loopback addresses
            if (current_ip != "127.0.0.1") {
                ip = current_ip;
                break; // Grab the first non-loopback IP—adjust if you need a specific interface
            }
        }
    }
    freeifaddrs(ifap);
    return ip;
}

Then, in your logging logic, check if the DDS-provided IP is 0.0.0.0—if so, use the result from this function instead.

Key Notes

  • Link the Right Libraries: Make sure your build system links against RTI’s transport libraries (e.g., librti_udp_transport.so on Linux or rti_udp_transport.lib on Windows).
  • Custom Transports: If you’re using a non-UDP transport (like TCP or a custom one), adjust the code to check for that transport kind instead.
  • Multiple IPs: If your machine has multiple network interfaces, the code will return all bound IPs—you’ll need to add logic to pick the one relevant to your use case.

内容的提问来源于stack exchange,提问作者jgr208

火山引擎 最新活动