Blog

Enterprise Networking in LabVIEW 3

 As we approach the final solutions for 1:N and N:N communication using the TCP protocol, we have to take a break to cover some common problems with TCP communication and some solutions that we have found to be more than adequate. These solutions will increase scalability and reveal some of the reasons why communication can be difficult to get right. Example code Included!

TCP allows you to avoid explicitly packetizing your data, but when parsing received strings, safe type conversion becomes a challenge: knowing what the received data contains and being able to shuttle it around your architecture can help significantly.

VI Snippet defining the data types.

The example of a family of data types above allow for ‘safe type conversion’ that fails closed. Each type defintion only uses primitives and should never change or have to be recompiled by LabVIEW.

VI Snippet showing how to safely type cast with enums.

The type_enum_1 contains two dummy items in the enum for item 0 (<data_type>) and the final item <null> ensuring that if you typecast 'type_u16' and it uses a value that isn't defined, it won't masquerade as a valid type.

VI Snippet showing how to convert a received string into a specific packet.

By remaining static, you ensure backwards compatibility between versions and because of safe type conversion, you can code your software to fail closed, maintain existing functionality and safely add new functionality.

VI Snippet showing how to convert a packet into a string to send over a network.

 Although TCP is connection-oriented and has several built-in functions that help maintain the connection, in practice these don’t always work as expected.  Often, TCP/UDP errors can must be ignored or only paid attention to during development.

The easiest way to ensure that a connection is in good shape is using a heartbeat. A heartbeat for all intents and purposes is an empty packet than when received let’s either side know that the connection is up and working.  In the event the heartbeat is NOT received; the connection isn’t good and reconnection needs to occur.  Using this along-side checking for specific errors (e.g. error 1) will give you the most robust reconnection code.

Common errors:

  • 55 - this error occurs if you attempt to write to the same connection simultaneously and the connection times out before data can be sent
  • 56 - this is a general timeout, can happen in several situations, can sometimes be ignored, very common for a read function to time out constantly (i.e. no data being received)
  • 66 - this error occurs if a connection is closed by a peer (i.e. graceful close), doesn’t always mean that the connection has ‘died’ due to abstraction.
  • 1 - this error occurs if the tcp/udp reference becomes invalid

This link provides some information regarding errors 55/56.

Finally, because data must traverse a network or the internet, data may not make it to the destination in a reasonable amount of time or not at all.  Your code that waits on responses must decide that it has waited too long and give up.  Any downstream code that uses that must also be developed to handle situations where a network operation times out (or a connection dies mid-request).

Example code for this blog can be found here. In the final installment, we’ll show the generic architecture of how to create a 1:N TCP based communication application in LabVIEW.