7 Stimmen

Float-Array vom C++-Server an den C#-Client senden

Ich versuche, einige Daten von einem C++-Server an einen C#-Client zu senden. Ich war in der Lage, über Char-Arrays zu senden. Aber es gibt einige Probleme mit Float-Array.

Dies ist der Code auf der C++-Server-Seite

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

also ja, ich versuche, ein Float-Array der Größe 12 zu senden.

Hier ist der Code für die Client-Seite. (Es war seltsam, dass es keinen einfachen Weg gab, den Float aus dem Stream zu bekommen. Ich habe noch nie C# verwendet, und vielleicht gibt es etwas besser?)

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

Schauen wir uns den Speicherauszug auf beiden Seiten an, und das Problem wird klar sein -

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

Es gibt hier 2 Probleme auf der c#-Seite. 1) erstens verarbeitet es keine Daten über 0x80 (über 127) (inkompatible Strukturen?) 2) aus irgendeinem unglaublichen Grund fällt es ein Byte!!

und dies geschieht in "temp" direkt zum Zeitpunkt des Empfangs der Daten

Ich habe versucht, etwas herauszufinden, aber immer noch nichts. Haben Sie eine Idee, woran das liegen könnte? Ich bin sicher, ich mache etwas falsch... Haben Sie Vorschläge für eine bessere Vorgehensweise?

Herzlichen Dank!

5voto

Isak Savo Punkte 33709

Aus Ihrem Code geht nicht klar hervor, was die streamReader auf die die Variable zeigt (d.h. was ist ihr Typ?), aber ich würde vorschlagen, dass Sie die BinaryReader stattdessen. Auf diese Weise können Sie einfach Daten lesen ein Schwimmer nach dem anderen und sich nicht mit der byte[] Array überhaupt nicht:

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.

Unterschiedliche Leser machen unterschiedliche Dinge mit Daten. Der Text-Reader (und Stream-Reader) geht beispielsweise davon aus, dass es sich um Text in einer bestimmten Kodierung (z. B. UTF-8) handelt, und interpretiert die Daten möglicherweise auf eine Weise, die Sie nicht erwartet haben. Der BinaryReader wird das nicht tun, da er so konzipiert wurde, dass Sie genau die Datentypen angeben können, die Sie aus Ihrem Stream lesen wollen.

2voto

aib Punkte 42913

Ich bin mir bei C# nicht sicher, aber C++ gibt keine Garantien für die internen, binären Darstellungen von Floats (oder anderen Datentypen). Nach allem, was Sie wissen, könnte 0,42 mit diesen 4 Bytes dargestellt werden: '0', '.', '4', '2'.

Die einfachste Lösung wäre, menschenlesbare Zeichenketten wie "2.1 9.9 12.1 94.9 2.1" zu übertragen und cin/cout/printf/scanf und Konsorten zu verwenden.

1voto

Cem Kalyoncu Punkte 13357

Im Netz sollten Sie Ihre Zahlen immer in ein gängiges Format umwandeln und dann zurücklesen. Mit anderen Worten: Alle Daten, die keine Bytes sind, sollten gekapselt werden. Unabhängig von Ihrer Programmiersprache müssen Sie also genau das tun. Ich kann nicht sagen, was mit Ihrem Code nicht stimmt, aber das könnte Ihr Problem lösen und Ihnen später einige Kopfschmerzen ersparen. Überlegen Sie, ob die Architektur 64 Bit hat oder ein anderes Endian-Format verwendet.

EDITAR:
Ich vermute, Ihr Problem liegt mit signiert unsigned und kann mit Isak's Antwort gelöst werden, aber immer noch beachten, was ich gesagt hatte.

Wenn Sie Hilfe zur Verkapselung benötigen, sehen Sie in Beejs Network Guide nach. Es sollte ein Beispiel dafür geben, wie man Floats über ein Netzwerk kodiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X