Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send float array from C++ server to C# client

Tags:

c++

c#

sockets

I'm trying to send some data from a C++ server to a C# client. I was able to send over char arrays. But there is some problem with float array.

This is the code on the C++ server side

float* arr;
arr = new float[12];
//array init...
if((bytecount = send(*csock, (const char*)arr, 12*sizeof(float), 0))==SOCKET_ERROR){
}

so yes i'm trying to send over a float array of size 12.

here's the code for the client side. (it was strange that there was no easy way to get the float out of the stream in the first place. I have never used C# before and maybe there's something better?)

//get the data in a char array 
streamReader.Read(temp, 0, temp.Length);  
//**the problem lies right here in receiving the data itself

//now convert the char array to byte array
for (int i = 0; i < (elems*4); i++)           //elems = size of the float array
{
    byteArray = BitConverter.GetBytes(temp[i]);
    byteMain[i] = byteArray[0];
}

//finally convert it to a float array
for (int i = 0; i < elems; i++)
{
    float val = BitConverter.ToSingle(byteMain, i * 4);
    myarray[i] = val;
}

let's look at the memory dump on both sides and the problem will be clear -

//c++ bytes corresponding to the first 5 floats in the array
//(2.1 9.9 12.1 94.9 2.1 ...)
66 66 06 40    66 66 1e 41     9a 99 41 41    cd cc bd 42    66 66 06 40

//c# - this is what i get in the byteMain array
66 66 06 40    66 66 1e 41     fd fd 41 41    fd 3d  ? 42    66 66 06 40

there are 2 problems here on the c# side- 1) first it does not handle anything above 0x80 (above 127) (incompatible structures?) 2) for some unbelievable reason it drops a byte!!

and this happens in 'temp' right at the time of receiving the data

I've been trying to figure something out but nothing still. Do you have any idea why this might be happening? I'm sure I'm doing something wrong... Suggestions for a better approach?

Thanks a lot

like image 558
sg88 Avatar asked Jul 23 '11 17:07

sg88


3 Answers

It's not clear from your code what the streamReader variable points to (ie what's its type?) but I would suggest you use the BinaryReader instead. That way, you can just read data one float at a time and never bother with the byte[] array at all:

var reader = new BinaryReader(/* put source stream here */)
var myFloat = reader.ReadSingle();
// do stuff with myFloat...
// then you can read another
myFloat = reader.ReadSingle();
// etc.

Different readers do different things with data. For instance the text reader (and stream reader) will assume all is text in a particular encoding (like UTF-8) and may interpret the data in a way you didn't expect. The BinaryReader will not do that as it was designed to let you specify exactly the data types you want to read out of your stream.

like image 173
Isak Savo Avatar answered Nov 15 '22 01:11

Isak Savo


I'm not sure about C#, but C++ makes no guarantees about the internal, binary representations of floats (or any other data type). For all you know, 0.42 might be represented using these 4 bytes: '0', '.', '4', '2'.

The easiest solution would be transferring human-readable strings such as "2.1 9.9 12.1 94.9 2.1" and using cin/cout/printf/scanf and friends.

like image 34
aib Avatar answered Nov 15 '22 00:11

aib


In network, you should always convert your numbers into a common format and then read back. In other terms any data other than bytes should be encapsulated. So regardless of your programming languages, this is what you need to do. I cannot comment on what is wrong with your code but this might solve your issue and will save some headache later on. Think if the architecture is 64 bits or it uses different endian.

EDIT:
I guess your problem lies with signed unsigned and can be solved with Isak's answer, but still mind what I had said.

If you need help on encapsulation check Beej's Network Guide. It should have a sample how to encode floats over network.

like image 1
Cem Kalyoncu Avatar answered Nov 15 '22 02:11

Cem Kalyoncu