Jump to content

LabVIEW TCP Messaging to fixed sized "C" structures


Recommended Posts

NI provide a nice example of a "Simple TCP/IP Messaging Protocol" library at http://zone.ni.com/devzone/conceptd.nsf/webmain/

0986799C984500F886256F170079411E. Essentially it uses XML tags to transfer Metadata information prior to message data, and then references Metadata elements for each data transfer. The LabVIEW client at the other end of the TCP socket references the data descriptor back into the appropriate data structure.

However, this solution requires LabVIEW at both ends of the socket, and data is transfered via strings (bandwidth and CPU are not of concern). In my situation I have an existing network application that is expecting a documented "C" structure, often with binary data. The C code would be highly confused if it started receiving XML strings instead. I'm looking for a mechanism to have LabVIEW read and write such fixed size data structures:

struct example {

long code;

char StringInformation[40];

long Nvalues;
};

followed by an array of "Nvalues" floating point numbers. I do not have the opportunity to re-write the C application, but need to make the LabVIEW client talk to the existing "fixed size" binary protocol. I know I'll need to munge the byte ordering too, but there are existing subVIs for that.

Ideas or pointers, please!

Thanks,

Andrew

Link to comment

See the attached VI.

In LabVIEW you create a cluster with your data as {long,string,float[]}. This can't be flatten directly since a flattened LabVIEW string is headed with its length (which is fixed in your data format). The string is first converted to a cluster of 40 bytes. The same would be done on float data if it were of fixed size (array to cluster). However, the structure used to transmit array (long Nvalues, float data) is the same as LabVIEW flattens arrays so no conversion is required.

To read it is a little more involved since you have to read the float data length and after read the data.

Download File:post-447-1127195155.vi

Link to comment
  • 3 weeks later...

One thing that should be noted when passing data from G to C when using a Windows based machine is the expected "endian" style of the sender and the reciever. Labview is Big Endian (due to its Mac roots) so the byte order of any data type with more than one byte (i.e. every data type that is not U8, I8, or string charaters) is backwards to what the rest of a Windows machine is expecting (which is little endian). Macintosh users and Unix users probably don't have to worry about this, unless they have to interface to windows based machines.

-Pete Liiva

Link to comment

I greatly appreciate the comments received. I wasn't aware that LabVIEW was MAC-Endian :) - fortunately the command structure is such that it can automatically determine the endian-ness of the remote incoming data structure and translate to the local architecture (not quite like XDR, as there isn't a "network standard", just a recognition of how the other side is different). This comes from the program's history of communicating between multiple PCs (MSDOS) and SparcStations.

While coding away in LabVIEW, I did notice that the alignment rules are "unusual". For example:

struct example {

unsigned short VariableA;

unsigned long VariableB;

};

has a sizeof(struct example) = 8 in most "C" implementations, but a "Flatten to String" and TCP Write generate only six bytes of output. So I've had to clean up those poorly aligned structures and stick a padding short between VariableA and VariableB.

I have a couple of new questions I'll post in more appropriate places (feel free to help out some more!), but I wanted to express my gratitude for getting me "unstuck".

Thank you!

Link to comment
  • 2 weeks later...
I greatly appreciate the comments received. I wasn't aware that LabVIEW was MAC-Endian :) - fortunately the command structure is such that it can automatically determine the endian-ness of the remote incoming data structure and translate to the local architecture (not quite like XDR, as there isn't a "network standard", just a recognition of how the other side is different). This comes from the program's history of communicating between multiple PCs (MSDOS) and SparcStations.

While coding away in LabVIEW, I did notice that the alignment rules are "unusual". For example:

struct example {

unsigned short VariableA;

unsigned long VariableB;

};

has a sizeof(struct example) = 8 in most "C" implementations, but a "Flatten to String" and TCP Write generate only six bytes of output. So I've had to clean up those poorly aligned structures and stick a padding short between VariableA and VariableB.

I have a couple of new questions I'll post in more appropriate places (feel free to help out some more!), but I wanted to express my gratitude for getting me "unstuck".

Thank you!

Yes LabVIEW uses byte packing on all platforms except Sparc stations as far as I know. This is because Intel and PowerPC CPUs have generally no big penalty in accessing operands on other boundaries than its integral operand size but a SPARC CPU has a huge penalty in those cases.

Rolf Kalbermatter

Link to comment
  • 1 month later...

I'm new here, looks like a very nice forum.

I want to do the same thing as the original poster, execpt I'm reading off of a tcp/ip connection instead of writing. If I knew the first thing about labview, I'm sure this vi would be very useful. We already have filter applications which could send out network data in strings if needed, but I'm not sure the performance would be acceptable.

In C there are functions ntoh_ (network to host _) and hton_ (host to network _) which do the byte swapping as required for the data type _. It looks to me as if the byteswap functions in labview swap bytes no matter what, which is not the behavior of ntoh_, which only swaps if the native format isn't swapped. If labview uses network order, I suppose I could skip the byte swapping, but it's not good form. Anyone can confirm this?

I have never seen anyone byteswap floating point numbers since almost all computers use IEEE formats as their native format. The NI site is the first mention of byteswapping floats I have ever seen.

Link to comment

We did get the read to work. It turns out that our situation was somewhat more complicated because we alternate messages with different formats. However all messages are preceded with a fixed format header. We didn't use byte swapping on the labview side; the c++ side does byte swapping to network format.

Now we have to figure out how to put the network code in a separate thread.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.