Отправить массив с плавающей точкой с сервера C ++ клиенту C # - PullRequest
7 голосов
/ 23 июля 2011

Я пытаюсь отправить некоторые данные с сервера C ++ клиенту C #.Я был в состоянии отправить массивы символов.Но есть некоторая проблема с массивом с плавающей точкой.

Это код на стороне сервера C ++

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

, так что да, я пытаюсь отправить массив с плавающей запятой размером 12.

вот код дляна стороне клиента.(было странно, что не было простого способа вытащить float из потока, во-первых. Я никогда раньше не использовал C # и, может быть, есть что-то лучше?)

//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;
}

давайте посмотрим на памятьдамп с обеих сторон, и проблема будет понятна -

//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

здесь есть 2 проблемы на стороне c # - 1) сначала он не обрабатывает ничего выше 0x80 (выше 127) (несовместимые структуры?) 2) по какой-то невероятной причине он сбрасывает байт !!

, и это происходит в 'temp' прямо во время получения данных

Я пытался что-то выяснить, но пока ничего,У вас есть идеи, почему это может происходить?Я уверен, что я делаю что-то не так ... Предложения для лучшего подхода?

Большое спасибо

Ответы [ 3 ]

5 голосов
/ 23 июля 2011

Из вашего кода неясно, на что указывает переменная streamReader (то есть на какой она тип?), Но я бы посоветовал вам использовать вместо нее BinaryReader .Таким образом, вы можете просто читать данные по одному с плавающей запятой за раз и вообще не беспокоиться о массиве byte[]:

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.

Разные читатели делают разные вещи с данными.Например, программа чтения текста (и потоковая программа чтения) предположит, что все является текстом в определенной кодировке (например, UTF-8), и может интерпретировать данные так, как вы этого не ожидали.BinaryReader не будет этого делать, так как он предназначен для того, чтобы вы могли точно указать типы данных, которые вы хотите прочитать из своего потока.

1 голос
/ 23 июля 2011

Я не уверен насчет C #, но C ++ не дает никаких гарантий относительно внутреннего, двоичного представления чисел с плавающей запятой (или любого другого типа данных). Для всех, что вы знаете, 0,42 может быть представлено с помощью этих 4 байтов: «0», «.», «4», «2».

Самым простым решением было бы перенести понятные человеку строки, такие как "2.1 9.9 12.1 94.9 2.1" и использовать cin / cout / printf / scanf и друзей.

1 голос
/ 23 июля 2011

В сети вы всегда должны конвертировать свои числа в общий формат и затем читать обратно.Другими словами, любые данные, кроме байтов, должны быть инкапсулированы.Таким образом, независимо от ваших языков программирования, это то, что вам нужно сделать.Я не могу комментировать, что не так с вашим кодом, но это может решить вашу проблему и в дальнейшем избавит вас от головной боли.Подумайте, является ли архитектура 64-битной или использует другой порядковый номер.

РЕДАКТИРОВАТЬ:
Я думаю, ваша проблема заключается в подписанном неподписанном и может быть решена с помощью ответа Исака, но все же помните, что я сказал.*

Если вам нужна помощь по инкапсуляции, проверьте руководство по сети Beej.В нем должен быть пример, как кодировать поплавки по сети.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...