Under which circumstances will Connext DDS send non-user data?

When we call DataWriter::write(), we expect to see a user data packet sent on the wire, but under what conditions will Connext DDS send packets of its own accord?

There are many reasons why Connext DDS may send messages other than user data. Some of the more common reasons are described below. Note that the non-user data messages described below are not sent by the DataWriters and DataReaders that you create in your application, but by builtin DataReaders and DataWriters.

In order to visualise the various packets explained in this article for yourself, it is recommended to use wireshark. Wireshark is shipped with an RTPS dissector which can be used to show the information contained within the packets described in this article. This Knowledge Base article explains how to configure wireshark to colourise RTPS packets.


When using reliable communication, DataWriters will send Heartbeat (HB) packets alongside each user data packet. HB packets can be sent either separately (periodic HBs) or within the same packet as the user data (piggyback HBs). HB packets inform the DataReader which user data packets it should have received. In the WireShark dissector, the sequence number field shows which packets the DataWriter is saying are available with the HB. The DataReader then responds to the HB with an ACKNACK. The ACKNACK informs the DataWriter whether or not any of the user data packets need to be resent.

Preemptive HB and ACKNACKs

Preemptive HB and ACKNACK packets are sent before discovery begins. They are used to kick-start the discovery process.

Participant Discovery

During participant discovery, by default, a participant will send 5 announcements to its initial peers (these packets are sent as best effort and so are not accompanied by HBs or ACKNACKs). The number of packets which it sends is configurable through the initial_participant_announcements fields in the DiscoveryConfig QoS policy. In WireShark’s RTPS dissector, these packets are displayed as DATA(p).

Throughout its life, a participant will assert its liveliness by re-sending these DATA(p) packets. By default, these packets are sent every 30 seconds, but this interval is configurable through the participant_liveliness_assert_period field in the DiscoveryConfig QoS policy.

This Knowledge Base article explains how to determine when discovery is complete using wireshark.

Endpoint Discovery

Once participant discovery has completed, endpoint discovery begins. Endpoint discovery packets (shown as DATA(r) and DATA(w) in WireShark’s RTPS dissector) are sent using reliable communication, meaning you will also see HBs and ACKNACKs.

Endpoint Liveliness

Endpoints (DataWriters and DataReaders) can be configured to assert liveliness automatically or manually. The DDSDataWriter::assert_liveliness() function is used to assert liveliness manually. Calling this function will send a  liveliness packet on the network (which is displayed as DATA(m) in WireShark’s RTPS dissector). When the default liveliness kind of DDS_AUTOMATIC_LIVELINESS_QOS is used (in the Liveliness Qos policy), it is not necessary to assert liveliness manually.

Resent Participant Announcements

If a participant receives a DATA(p) packet from a late-joining participant that is in its initial peers list, it will resend its DATA(p) to all of its peers.

QoS Modifications

If they are modified during runtime, certain QoS policies will be propagated to matching entities. These modifications are communicated using DATA(p) packets. Only QoS policies which are mutable can be modified.

Dispose and Unregister Messages

Dispose and Unregister messages are propagated to all matching entities. These messages are sent as DATA(p) messages. They are shown as DATA(p[UD]) packets in WireShark’s RTPS dissector (where [U] signifies an unregister message and [D] signifies a dispose message).

Gap Messages

Gap messages are sent from a DataWriter to a DataReader to indicate that some specific samples are not relevant. When writer-side filtering is being used (e.g., when using a Content Filtered Topic), the DataWriter will send gap messages to indicate to the DataReader not to worry about the samples that have been filtered.
The DataWriter will also send gap messages during reliable, keep_last communication, if samples are replaced in the DataWriter’s history queue before a DataReader has received them.

Content Filtered Topic

When a subscribing application creates or modifies a Content Filtered Topic, the filter expression and parameters will be sent to the publishing application. The creation of this Content Filtered Topic (or the modification of its filter parameters and expression) can happen at runtime. The information is sent  within a DATA(r) packet.

TopicQuery Creation

When a DataReader calls DDSDataReader::create_topic_query(), Connext DDS will propagate TopicQueries to other DomainParticipants and their DataWriters.
These requests are handled using the built-in ServiceRequest
DataReaders and DataWriters which communicate over a separate channel; the ServiceRequest channel. Two channels are used so that live and historical data be received by the subscribing application in parallel.
When a matched
DataWriter receives the TopicQuery it was respond by sending any cached samples which pass the TopicQuery’s filter.
The ServiceRequest channel is only used to handle the TopicQuery requests, the historical data is sent through the same channel as live data.