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.
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.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.
Then, compile your application using Visual Studio or make.
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; orLD_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 setNDDSHOME
and you are using BASH: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:On the Subscriber's side, as
dds.transport.TCPv4.tcp1.server_bind_port
is 7401 on the Publisher run: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.
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.
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
Hello,
I trty to run the tcp transport example, and the subscriber getting following errors, any advice?
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.
Hi Howard,
Thank you for the replies. I am running on the same machine but they are using the deferent ports(7400 and 7401)
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.
Hi Howard,
Thank you again for the replies, indeed I have a port conflicts on my machine, it works now.
- Richard
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?
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.