From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Labview double array to C# program via TCP/IP

Can someone explain how to transfer a large array of double precision data to a c# program via TCP/IP? The question is more related to typecasting. So far, the solution i came up with is to do number-to-fractional-string on labview side (8 byte each), then concatenate all the strings and send it out over TCP. On the C# side, I read out all the message to one byte[] array, then convert each 8 byte to a number in a for loop. It works, but I don't think it's the most efficient approach. Both sides of the program involve a loop which takes some time, as the array grow bigger (>10,000 elements). Any suggestions?

Thanks.

0 Kudos
Message 1 of 14
(6,638 Views)

You should use the Type Cast function instead of the Number to Fractional String function. The Type Cast function will return a string that is always 8 bytes, the same size as a DBL. The Number to Fractional String function will return a string that will vary in length, depending on the number. For example:

 

 

On the C# side I think you can treat the stuff coming in over the TCP/IP as a byte array which you can then cast/convert. I'll have to check on this tomorrow.

Message Edited by smercurio_fc on 07-21-2009 08:41 PM
0 Kudos
Message 2 of 14
(6,629 Views)

I have tried to use type cast, but failed to cast it back on the C# side. This is why I settled on the number to string. It will be helpful if you can provide me a C# example.

Thanks.

0 Kudos
Message 3 of 14
(6,615 Views)

Sorry for the delay in getting back. OK, on the C# side you would be reading the data coming over the TCP/IP as a byte array. You can convert the byte array to an array of doubles using the Buffer.BlockCopy method. Here's an example:

 

            byte[] byteArray = {205, 204, 204,  204, 204, 204, 0, 64, 154, 153, 153, 153, 153, 153, 1, 64};
            double[] dblArray = (double[])Array.CreateInstance(typeof(System.Double), Buffer.ByteLength(byteArray) / 8);
            Buffer.BlockCopy(byteArray, 0, dblArray, 0, Buffer.ByteLength(byteArray));
 

The above is an example of having a byte array of 16 bytes. This corresponds to 2 doubles. When the code completes the variable dblArray will contain 2 doubles, values 2.1, and 2.2. The BlockCopy operation should be very fast.

 

The likely problem you will have is the order of the bytes. If on the LabVIEW side you use Type Cast, then the byte order will not come in the way it's expected at the C# side. You will need to use Flatten To String, explicitly specifying endianness:

 

 

Message Edited by smercurio_fc on 07-22-2009 02:30 PM
0 Kudos
Message 4 of 14
(6,602 Views)

Thank you very much. It works with little-endian.

 

0 Kudos
Message 5 of 14
(6,567 Views)

I have a similar issue, if you send the data as a Binary String over the TCP connection, how on the C# side do you convert that back into the Double? The example C# code above shows the data already as a byte array, how can I convert the binary string into the byte array on the C# side? Apologies if I've missed something obvious but I'm not up to speed on C#.

Regards.

0 Kudos
Message 6 of 14
(6,102 Views)

 


@AndrewElite wrote:

I have a similar issue, if you send the data as a Binary String over the TCP connection, how on the C# side do you convert that back into the Double? The example C# code above shows the data already as a byte array, how can I convert the binary string into the byte array on the C# side? Apologies if I've missed something obvious but I'm not up to speed on C#.

Regards.


On the C# side the TCP/IP functions would be provided a character array to use as the buffer for the data read from the network stream. The TCPListener class documentation on MSDN provides an example. As you can see from the example, a char[ ]  is created as the buffer and used by Read method of the NetworkStream object.

 

0 Kudos
Message 7 of 14
(6,083 Views)

Thanks for the reply, but I am still a bit lost. Looking at the example of TCPListener class on the MSDN page, there is no mention of char[].

 

On the Labview side we flatten double data to a binary string using flatten to string (little-endian) and then send over the TCP. On the C# side, when we recieve the data it appears as a number of ascii characters i.e. in little-endian format a value of 12 arrives as (@ preceeded by 6 null characters and we are unable to decode it. With data coming the other way, TCPListener sends the data (again 12) as a byte array, which appears to leave the C# side as decimal acsii-encoded values 50 49 48 48 48 48 48 48 arriving from the LabVIEW TCP connection as 21000000 which is the little-endian 12, so we don't appear to need unflatten from string on the LabVIEW side.

 

I'm obviously missing something no doubt obvious. Would there be any chance of seeing the C# code that will convert the binary string to a double array and also the code that converts a double to a binary string that makes sense when using unflatten from string on the LabVIEW side. I've attached the LabVIEW write and read code below.

 

Apologies again if I'm missing something obvious.

 

Thanks again.

0 Kudos
Message 8 of 14
(6,061 Views)

In the TCPListener example you will see this line:

 

Byte[] bytes = new Byte[256];

That's the buffer. "char" is the old C datatype. Its storage amount is the same as the Byte class in .NET.

 

On the C# side the data you get is not a number of ASCII characters. It's a series of bytes. You can interpret it as a number of ASCII characters if the byte values correspond to the ASCII codes for characters. You have to understand the distinction.

 

I don't have the code that you are requesting, and unfortunately I don't have time right now to whip up a simple example. I may have time to do so later today.

0 Kudos
Message 9 of 14
(6,044 Views)

One of the problems you have is that the Flatten To String function will, by default, pre-pend the array size. I do not know if you are accounting for this in your C# code since you do not show the C# code.

 

On the C# side the Read will allow you to read in a sequence of bytes. Then you can convert to an array of numbers as I had shown. See attached VI and C# example. Note that this is a crude example. The receiver should be told how many bytes to read, so there should be a byte count or a qty of numbers sent before the actual data so the receiver knows how many bytes to expect.

Download All
0 Kudos
Message 10 of 14
(6,000 Views)