Which socket channel is used to send/receive user data?

2 posts / 0 new
Last post
Last seen: 9 years 2 months ago
Joined: 04/16/2015
Posts: 11
Which socket channel is used to send/receive user data?

I see that the domain participant creates three built-in Data Writers and three built-in Data Readers. The first two reader/write are used to discover other domain participant. The other two are used for dicover endpoints. I have below questions regarding this design:

1. Why do we need two writers and two readers for endpoint discovery?

2. Who will send/receive user data during communcaiton? Which port number will be used to transfer user data among different peers?

3. If I create many topics under one domain, do they share one socket channel during data transfer? 


Zhao Yi

Gerardo Pardo's picture
Last seen: 1 month 1 week ago
Joined: 06/02/2010
Posts: 602


I will try to address your three questions in order:

Need for multiple writers/readers for discovery:

The fact that DDS uses 3 different DataWriters for discovery: one for DomainParticipants, Publications, and one for Subscriptions is part of the Standard DDS Interoperability Protocol (RTPS). We decided that it was better to use 3 different Writers for several reasons:

(1) It allows the data-type to be more narrowly defined (e.g. the DataReader for Subscriptions is associated with the "subscriptions" data-type which is different from the "publications" data-type).

(2) It supports better a common case where applications are only intrested in being notified on some o fthe discovert info (e.g. only Participants) havig multiple Topics allows the application to just monitor this.

(3) It makes it easier to implement different discovery protocols. For example RTI Connext supports a combination of dynamic and static discovery whereby the presence and location of participants used the standard "Participants" builtin topic and the actual endpoints obtained from a different source (e.g. read from XML files).

(4) Having more endpoints is not significant in terms of resources because these are "builtin" endpoints. They are automatically creates, do not need to be discovered, share the same ports and threads, etc.

Second question about who sends user data:

The "sending" port for user data is autimatically determined by the trabsport. In the case of UDP it is automatically selected by the operating system as it does not have effect on the communication. Other transports like "shared memory" do not have a concept of a "send port". In general DDS applications do not concern themselves with the lower level transport issues. However for the situations where the application does care about transport configuration the different transports offer ways to configure their interbal behavior. Normally this uses properties. See for example section "15.6 Setting Builtin Transport Properties with the PropertyQosPolicy" of the RTI Connext DDS User's Manual.  However the "send port" is not one of the things you can configure. Is there a reason you need this? If required it would be certainly possible to extend the UDP transport Plugin to accept this configuration... but so far we have not encaiutered this use-case.

Third question on sharing sockets among topics:

As far as sending all UDP user data sent by a DomainParticipant uses the same send socket as long as the traffic has been configured to have the same TRANSPORT_PRIORITY. This is the default so with the "out-of-the-box" settiings there will be a single UDP send socket used for both unicast and multicast, discovery, and user data. However you can configure the TRANSPORT_PRIORITY policy on the DataWriterQos to force using a different socket for that DataWriter/Priotity and simlartly the metadata_transport_priority in the DomainParticipant's  DiscoveryQosPolicy to force a sparate socket to send meta-data.

As far as receiving each UDP "receive" port uses a single socket. By default (out-of-the-box) there are 3 "UDP receive" ports: Multicast discovery, Unicast discovery, and user data. So there will be 3 sockets. You can configure that specific DataReaders use different ports using the DataReaderQos. Specifically the TRANSPORT_UNICAST and TRANSPORT_MULTICAST Qos Policies. This will result in additional ports, sockeks, and thread. The rule out UDP plugin implements is "one thread per socket, one socket per port". This avoids thread contention between sockets. 

Hope this clarifies things a little. The answer is complicated because we are trying to use sensible settings out of the box and at the same time allow configurability so that application-specific needs can be met. Also DDS uses multiple transports in addition to UDP (shared memory, TCP, TLS, etc.) and these tradeoffs are necessaritly transport specific.

Let us know if you have additional questions or if this behavior does not match your intended use.