Edit Transport using Participant QoS Properties

11 posts / 0 new
Last post
Offline
Last seen: 10 years 8 months ago
Joined: 11/20/2012
Posts: 4
Edit Transport using Participant QoS Properties

Hello,

I'm trying to change the underlying transport of all of my participants from UDP to TCP v4 LAN.  I'm running on Windows using 4.5f.  I'm setting the transport programatically in the participant Qos at participant creation.

Could you please tell me what I am doing wrong below?  I dont receive any error notifications from DDS nor are any of my subscribers receiving any data from the Publishers. 

I've added system variable NDDS_DISCOVERY_PEERS with a value of tcpv4_lan://myhostname:myport

Also included the nddstransporttcp library as part of my build.

DDS_DomainParticipantQos participant_qos;

DDSDomainParticipantFactory::get_instance()->get_default_participant_qos(participant_qos);

participant_qos.transport_builtin.mask = DDS_TRANSPORTBUILTIN_MASK_NONE;

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.load_plugins", "dds.transport.TCPv4.tcp1",DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.library", "nddstransporttcp",
DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.create_function","NDDS_Transport_TCPv4_create", DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.parent.classid",
”NDDS_TRANSPORT_CLASSID_TCPV4_LAN”,
DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.server_bind_port", myport,
DDS_BOOLEAN_FALSE);

participant = DDSTheParticipantFactory->create_participant (domainId,
participant_qos, NULL, DDS_STATUS_MASK_NONE);


(All participants are created sucessfully but the data is not received by the subscribers).  Note:  the same code above is used to create the Publisher and Subscriber domain participants.   Both participants are on the same machine.

Thank you for your help.

Fernando Garcia's picture
Offline
Last seen: 3 months 2 weeks ago
Joined: 05/18/2011
Posts: 200

Hi Techgeek,

I have written a simple example application that illustrates how to use the TCP v4 LAN transport. It sets up the participant following the settings you added in your post.

Note that the Publisher and Subscriber application's participants share the same QoS settings I set in the snippet below. The only difference is that the value of dds.transport.TCPv4.tcp1.server_bind_port is different in the Publisher and Subscriber applications (i.e., 7400 in the Publisher application, and 7401 in the Subscriber application). The reason for using different ports is to be able to test the application using localhost.

    char myport[5] = "7400" // Set it to 7401 in the subscriber application
    DDSDomainParticipantFactory::get_instance()->get_default_participant_qos(participant_qos);
    
    participant_qos.transport_builtin.mask = DDS_TRANSPORTBUILTIN_MASK_NONE;
    
    DDSPropertyQosPolicyHelper::add_property(participant_qos.property,
					     "dds.transport.load_plugins", 
					     "dds.transport.TCPv4.tcp1",
					     DDS_BOOLEAN_FALSE);
    
    DDSPropertyQosPolicyHelper::add_property(participant_qos.property,
					     "dds.transport.TCPv4.tcp1.library",
					     "nddstransporttcp",
					     DDS_BOOLEAN_FALSE);
    
    DDSPropertyQosPolicyHelper::add_property(participant_qos.property,
					     "dds.transport.TCPv4.tcp1.create_function",
					     "NDDS_Transport_TCPv4_create", 
					     DDS_BOOLEAN_FALSE);

    DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
					      "dds.transport.TCPv4.tcp1.parent.classid",
					      "NDDS_TRANSPORT_CLASSID_TCPV4_LAN",
					      DDS_BOOLEAN_FALSE);
    
    DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
					      "dds.transport.TCPv4.tcp1.server_bind_port",
					      myport,
					      DDS_BOOLEAN_FALSE);

To run the example unzip tcpv4_lan_example on any directory and run rtiddsgen to generate makefiles or Visual Studio projects you will need to compile. Note that you will see some warning messages because as of the existing files will not be replaced with updated content by rtiddsgen.

rtiddsgen -example i86Linux2.6gcc4.4.3 -language C++ hello_tcp.idl
File /home/fgarcia/rti/test/tcpv4_lan_example/hello_tcp_subscriber.cxx already exists and will not be replaced with updated content. If you would like to get a new file with the new content, either remove this file or supply -replace option.
File /home/fgarcia/rti/test/tcpv4_lan_example/hello_tcp_publisher.cxx already exists and will not be replaced with updated content. If you would like to get a new file with the new content, either remove this file or supply -replace option.
File /home/fgarcia/rti/test/tcpv4_lan_example/USER_QOS_PROFILES.xml already exists and will not be replaced with updated content. If you would like to get a new file with the new content, either remove this file or supply -replace option.
Done

Then, compile your application using Visual Studio or make.

make -f makefile_hello_tcp_i86Linux2.6gcc4.4.3

Before running the application you have to configure a few things. First, you will need to add the NDDSHOME/lib/<platform_name> directory to Path, if you are using Windows; or LD_LIBRARY_PATH, if you are using Linux. The reason to add this folder to your environment, is that we configured the participant to load nddstransporttcp.dll (or libnddstransporttcp.so in Linux) without specifying its location. For instance on Linux, assuming we have already set NDDSHOME and you are using BASH:

export LD_LIBRARY_PATH=$NDDSHOME/ndds.5.0.0/lib/i86Linux2.6gcc4.4.3:LD_LIBRARY_PATH

Then, set the NDDS_DISCOVERY_PEERS on both Publisher's and Subscriber's application environment and run the applications. On the Publisher side, remember dds.transport.TCPv4.tcp1.server_bind_port is 7401 on the Subscriber's participant, you need to add that port to communicate with the Subscriber. Again, assuming you are using Linux and BASH:

export NDDS_DISCOVERY_PEERS=tcpv4_lan://localhost:7401
./objs/i86Linux2.6gcc4.4.3/hello_tcp_publisher 
=====================
Publisher Application
=====================
dds.transport.tcp.tcp1.server_bind_port = 7400
Writing hello, count 0
Writing hello, count 1
Writing hello, count 2
Writing hello, count 3
Writing hello, count 4
Writing hello, count 5

On the Subscriber's side, as dds.transport.TCPv4.tcp1.server_bind_port is 7401 on the Publisher run:

export NDDS_DISCOVERY_PEERS=tcpv4_lan://localhost:7400
./objs/i86Linux2.6gcc4.4.3/hello_tcp_subscriber
=======================
Subscriber Application
=======================
dds.transport.tcp.tcp1.server_bind_port = 7401
hello subscriber sleeping for 4 sec...
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 2
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 3
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 4
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 5

Your Subscriber application may miss the first few samples. Use TRANSIENT_LOCAL in the DataWriter and DataReader if you do not want to lose these samples (see this solution on the Knowledge Base).

Let me know if this solves your issue,

Best regards,
Fernando.

File Attachments: 
Offline
Last seen: 10 years 8 months ago
Joined: 11/20/2012
Posts: 4

Hi Fernando,

Thank you for the post, and for the sample code. 

With the TCP configuration on Windows, I receive the following error (consistently on the subscriber and randomly on the publisher):  NDDS_Transport_TCPv4_Plugin_verifySendResourceState_clientEA:detected send resource in an invalid state: SR=CONNECTING, CC=BOUND, DC=DISCONNECTED

What triggers this notification? 

I added on_publication_matched callback for writer discovery of the reader to complete before writer transmits any data.  The first few samples continue to be dropped as indicated in the note.  We thought that changing the underlying transport to TCP would address this.  Is there a mechanism to prevent losing the first few samples without using Durable or Reliable QoS or additional sleeps on the writer.  Usage of Durable/Reliable introduces delays that affect our high speed data transmission requirements.

Thank you again.

Gerardo Pardo's picture
Offline
Last seen: 2 days 18 hours ago
Joined: 06/02/2010
Posts: 602

Hello,

Switching to a TCP transport will not solve the issue of missing the first samples.  TCP is realiable, yes. But UDP with RELIABILITY turned on is just as reliable.  

The issue of missing the first samples comes from the fact that the DataWriter writes them before it disovers the DataReader and unless the DURABILITY QoS is set to a kind different from the default (VOLATILE) these "previously written samples" are not sent to the "late joining" DataReader.

You can find more details along with guidance on how to configure the system to not lose the first samples in these two threads:

http://community.rti.com/content/forum-topic/subscriber-does-not-receive-first-sample

http://community.rti.com/kb/why-does-my-datareader-miss-first-few-samples

Gerardo

 

rwu
Offline
Last seen: 2 years 3 months ago
Joined: 07/07/2022
Posts: 4

Hello,

I trty to run the tcp transport example, and the subscriber getting following errors, any advice?

 

Howard's picture
Offline
Last seen: 1 day 16 hours ago
Joined: 11/29/2012
Posts: 605

The error shows that the TCP transport plugin could not bind to the socket port.  Are you running multiple applications on the same machine?  If so, they all need to use different TCP ports.

The example was designed to run on 2 different machines.  If you are trying to run on the same machine, you need to set different ports for the publishing application and the subscribing application and then adjust the configuration of the initial peers to reflect your port numbers.

rwu
Offline
Last seen: 2 years 3 months ago
Joined: 07/07/2022
Posts: 4

Hi Howard,

Thank you for the replies. I am running on the same machine but they are using the deferent ports(7400 and 7401)

Howard's picture
Offline
Last seen: 1 day 16 hours ago
Joined: 11/29/2012
Posts: 605

Does the error occur for both applications or only the one on 7401? 

If only on 7401, then try a different port like 7500.

I think that the TCP transport actually opens multiple ports, so if you specify 7400, the same participant may be opening 7401 as well?  You can check with the netstat command.

rwu
Offline
Last seen: 2 years 3 months ago
Joined: 07/07/2022
Posts: 4

Hi Howard,

Thank you again for the replies, indeed I have a port conflicts on my machine, it works now.

- Richard

rwu
Offline
Last seen: 2 years 3 months ago
Joined: 07/07/2022
Posts: 4

Hi All,

I tried to use TCP as DDS transport,  in comparison with UDP transport, it becomes a peer to  peer  comminucation, that is in order to commiinucate peers has to know theirs ip address and port details. if I have a pub/sub scenario where  one publisher and multiple subscribers, so the publisher needs to know each subscriber's host and port for discovering each other?

 

Howard's picture
Offline
Last seen: 1 day 16 hours ago
Joined: 11/29/2012
Posts: 605

Hi Richard,

You can run the TCP transport in a client/server configuration where the clients know the server's IP/port but the server doesn't need to be preconfigured with the clients info.  This is simply done by only configuring the initial_peers QoS of the client apps with the Server's IP:port and leaving the server's initial_peers empty (or only configured to connect to other apps that it should know about for other transports like UDP).

When the client starts, it will connect to the server via it's initial_peers list.  And the server will accept the "connection" by responding with its own discovery information.

Note that this also works for UDP transports (actually any transport).  Only one side needs to know about the address of the other side to initiate a connection between the two.

The cavaet is that if you start the server, it doesn't try to connect to any apps since its initial_peers is empty.  It's up to the "client" apps to discover the server...which may be delayed for 30 seconds by default, since by default, the QOS is configured to send discovery info periodically, once every 30 seconds.