LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

what is the best way to parse TCP data packets?

As a side-note, unless you're using an old version of LabVIEW, use the enumeration for the endianness input, instead of a number; it will be easier to read. Remove the "1" and right-click the endianness input of unflatten from string, then choose Create Constant.

0 Kudos
Message 41 of 50
(2,354 Views)

Steve wrote:

Can you write down, in words, what is the meaning of the string:

4200 0000 A3CF A100 0000 00  ?

 

If you can't, you shouldn't be writing code yet - not until you nail that down.

 

If you can, then can you explain why the "Packet size" is 0x42 (d66), but your result string is only 11 bytes long?

 

4200 0000 A3CF A100 0000 0000  

 

The first part of this is a TCP wrapper which is embedded in every packet of TCP data in this application.

 

The breakdown of it is:  (Big Endian orientation)

 

4200 = Size of TCP packet in bytes (42h = 66 bytes of data)
0000 = Sequence ID of the TCP packet
A3CF A100 0000 0000 = Padded data (not used)


To answer your other question
If you can, then can you explain why the "Packet size" is 0x42 (d66), but your result string is only 11 bytes long?

 

This is what I am trying to figure out as the Hexadecimal String To Number Function is returning 11 when I input the 42h.

 

Any idea why it is doing that?
.

0 Kudos
Message 42 of 50
(2,324 Views)

The first part of this is a TCP wrapper which is embedded in every packet of TCP data in this application.

 

 

--- Then it's exactly the right thing to do, to define a structure (cluster) with those words in it.

 

The breakdown of it is:  (Big Endian orientation)

 

4200 = Size of TCP packet in bytes (42h = 66 bytes of data)

 

 

 

--- That's not big endian, since the LSB is first.

 


0000 = Sequence ID of the TCP packet
A3CF A100 0000 0000 = Padded data (not used)

 

--- If I were you, I would define a CLUSTER with

U16 Packet Size

U16 Sequence ID

U16 Pad 0

U16 Pad 1

U16 Pad 2

U16 Pad 3

 

 

You have a diagram instance of that (data irrelevant).  

You get the SIZE of it via FLATTEN + STRING LENGTH.

You read that many bytes.

You UNFLATTEN it into a structure. (you have a big-endian / little endian option here).

You extract the PACKET SIZE from the header.

You calculate the PAYLOAD size (assuming that PACKET SIZE includes the header too).

You read the PAYLOAD.

You do something with the payload.

 Header+Payload.PNG

 

 

 

 

 

This is what I am trying to figure out as the Hexadecimal String To Number Function is returning 11 when I input the 42h.

 

Note that just because you chose to DISPLAY a string in HEX notation, it doesn't mean the string is HEX characters.

 

If I give you a string with  one single, solitary byte (8 bits) with a value of 0x41,  you can display it as :

--- A string, and you see an "A"

--- 0x41, if you choose HEX display

 

THE DATA DOESN"T CARE which way you display it - you stlil have a single byte.

 

So there's no way that HEX STRING TO NUMBER will do anything good for you.

 

IT'S ALREADY A NUMBER.  Just use it, as per the diagram above.

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 43 of 50
(2,319 Views)

This works great and I really appreciate your help but there is one thing that needs to be tweaked just a little bit...

 

The packet size is actually a word and with the big endian byte order...

(So 0E01 = 1E0)

 

How can this number of bytes to read be calculated?

 

parse.jpg

 

Thanks much!

 

0 Kudos
Message 44 of 50
(2,277 Views)

Use Join Numbers on the Numeric >> Data Manipulation palette.

0 Kudos
Message 45 of 50
(2,265 Views)

You're making this more difficult that it really is.

 

The example I gave showed that you UNFLATTEN the string as a cluster of U16s, using a BIG ENDIAN selector (just a guess).

 

If what you have is a Little-Endian U16, then why take it apart? 

 

The items in the PACKET HEADER were U16 to begin with (I should have shown that)

 

Flip the selector to Little Endian, and be done with it.

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 46 of 50
(2,248 Views)

Thanks Steve, setting it to little endian works well.


I use the size of the packet (from TCP1) to select a case structure which parses the data with a specific cluster but there are other packets
(of different lengths) that I don't care to parse but I still need to read the remaining data in those TCP packets order to correctly
index to the beginning of the next TCP data packet...

 

How do I handle these unwanted TCP packets with the case structure?

 

Is there default that I can use to just read the remaining number of bytes?

 

Thank you

 

tcp packet parsing.jpg

 

 

0 Kudos
Message 47 of 50
(2,211 Views)
Your code already reads all the data since the TCP read is outside the case structure, so I have no idea what you're asking. Your case structure must already contain a "default" case (if not, you'll get an error) - what's in it?
0 Kudos
Message 48 of 50
(2,200 Views)

Nathan is right - you've already read the whole string from the TCP connection.

If you have cases that you don't want to process, then use the DEFAULT case to just ignore them.

 

 

There is something really basic that you are not understanding.

I gave you an example with a constant that had BIG ENDIAN, NATIVE,  and LITTLE ENDIAN as choices, and you throw that away and substitute an integer "2".

 

Does that really help anybody?  Why do that?  Why do you deliberately throw my suggestions away?

 

Take a look at your structure:in the 0x42 case, you are unflattening the data in a given case, and then running it all outside the case,  Do you notice all those coercion dots?  That's work that you're makling the CPU do.

 

Do you really have a "Seq-ID" in all cases?  If you do, fine, but why isn't it a U16 in all cases?  If not, then the SeqID indicator should be inside the case that applies.

 

The cluster that you use to define the UNFLATTEN operation MUST match the data coming in. But if it matches the data coming in, you woudn't need to coerce it so much.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 49 of 50
(2,186 Views)

Sorry if I hit a nerve, and yes there is some basic things that I am not understanding which is why I came to this forum for help ...

 

From a functional perspective with the Unflatten From String Function, the interger 2 represents LITTLE ENDIAN byte order (at least that is what the Labview help states for this function). Perhaps not as aestetically appealing but seems to work regardless and definitely not  deliberately throwing your suggestions away...

 

I really do have a "Seq-ID" in all cases, but not sure the basis of your question "but why isn't it a U16 in all cases?"

 

"Take a look at your structure:in the 0x42 case, you are unflattening the data in a given case, and then running it all outside the case,  Do you notice all those coercion dots?  That's work that you're makling the CPU do."

 

I want to view the data regardless of the case. The case is only used to take the written TCP packet and to parse if with the
appropriate cluster. Some instances will require additioanl operations based upon the type of TCP packet (case) is read.

 

Also, Not too concerned about how much work the CPU is doing at this time...

 

 

0 Kudos
Message 50 of 50
(2,176 Views)