如何获取RTI DDS 5.2.3.17中远端DataReader/Subscriber的IP地址?
Got it, let's break down how to get the remote DataReader/Subscriber's IP address for your logging needs—this is a common use case, and there's a straightforward path using DDS's built-in discovery mechanisms.
方法1:通过Publication匹配事件 + Discovery数据查询
This is the most reliable approach because DDS automatically tracks matched remote entities, and you can capture that event to extract network details:
Step 1: Create a custom DataWriterListener to track matches
You'll override theon_publication_matchedmethod, which triggers whenever a new DataReader connects or disconnects from your DataWriter:class MyDataWriterListener : public DDSDataWriterListener { public: void on_publication_matched( DDSDataWriter* writer, const DDSPublicationMatchedStatus& status) override { // Only act when a new subscriber connects (positive count change) if (status.current_count_change > 0) { DDSDomainParticipant* participant = writer->get_participant(); if (!participant) return; // Fetch metadata for the newly matched subscription DCPSSubscriptionBuiltinTopicData sub_data; DDS_ReturnCode_t ret = participant->get_discovered_subscription_data( sub_data, status.last_subscription_handle); if (ret != DDS_RETCODE_OK) { // Handle error (log a message, etc.) return; } // Use the subscription's participant GUID to get the remote participant's data DCPSParticipantBuiltinTopicData part_data; ret = participant->get_discovered_participant_data( part_data, sub_data.participant_guid); if (ret != DDS_RETCODE_OK) { // Handle error return; } // Extract IPv4 address from the participant's locators for (int i = 0; i < part_data.user_traffic_locators.length(); ++i) { const DDSLocator_t& locator = part_data.user_traffic_locators[i]; if (locator.kind == DDS_UDPv4_LOCATOR_KIND) { // Convert the 32-bit address to a human-readable string char ip_str[16]; snprintf(ip_str, sizeof(ip_str), "%d.%d.%d.%d", (locator.address >> 24) & 0xFF, (locator.address >> 16) & 0xFF, (locator.address >> 8) & 0xFF, locator.address & 0xFF); // Log the IP (replace with your actual logging function) printf("Remote DataReader connected: IP = %s, Port = %d\n", ip_str, locator.port); } } } } };Step 2: Attach the listener to your DataWriter
When creating your DataWriter, pass in the custom listener to enable match tracking:MyDataWriterListener* writer_listener = new MyDataWriterListener(); DDSDataWriterQos writer_qos; participant->get_default_datawriter_qos(writer_qos); DDSDataWriter* data_writer = topic->create_datawriter(writer_qos, writer_listener, DDS_STATUS_MASK_ALL);
关键注意事项
- Locator Types: Use
user_traffic_locatorsfor data transfer addresses, ormetatraffic_locatorsfor discovery communication—they're often the same, but choose based on your needs. - IPv6 Support: If your environment uses IPv6, handle
DDS_UDPv6_LOCATOR_KINDseparately (you'll need to format the 128-bit address properly). - Error Handling: Don't skip error checks for
get_discovered_subscription_dataorget_discovered_participant_data—network issues or misconfigurations can cause these to fail. - Discovery Mode: This works with dynamic discovery (default). If you're using static discovery, you'll need to pre-configure participant addresses, but the listener approach still works for verifying connections.
关联消息与接收者(进阶)
If you need to log which specific DataReader received a particular message, you'll need to add custom tracking:
- When a DataReader matches, store its GUID and IP in a map.
- Use RTI's Acknowledgment Manager (if enabled) to track message delivery, and map the acknowledgment's source GUID to the stored IP. Note that this requires configuring QoS for reliable delivery.
内容的提问来源于stack exchange,提问作者jgr208

