Daten Byteweise behandeln bzw. in anderen Datentyp umwandeln
-
Moin,
Aktuell versuche ich mich daran, einen Server für ein Spiel zu schreiben. (Ein Kumpel von mir hat einen, jedoch sehr verbuggt und in Java) Das Protokoll für die Datenübermittelung habe ich soweit verstanden und das Grundgerüst steht.
Jetzt stoße ich allerdings auf ein Problem:
Das Protokoll arbeitet natürlich nicht mit Worten wie "Bewege X nach Y". Daher stellt sich mir jetzt das Problem die empfangenen Daten aufzuteilen und in die neuen Datentypen zu übergeben.
Hier mal ein Beispiel:
Client Sendet: (uint)0x05(short)10(string)hi\0\0\0
(Die Werte mal zur veranschaulichung mit Dateityp, ich bekomme natürlich nur 0x050xA00x780x790x000x000x00)Wie bekomm ich jetzt die Werte in einzelne Variablen der Typen short und string?
(string ist 5 Byte groß, short 2 Byte, uint ist der Header)
-
du machst eine struct mit deinen daten, also alle variablen, so wie sie kommen in der Reihenfolge in der struct. dann alloziierst du speicher in der größe einer struct. liest in den speicher (pointer evtl. nach (unsigned)char casten) die daten aus dem netzwerk ein. dann castest du den pointer zum pointer-typ der struct. und tada!
achtung: im compiler member alignment ausschalten, weil der compiler sonst deine Variablen auf 2/4/x-Byte grenzen ausrichtet.
-
http://de.wikipedia.org/wiki/Speicherausrichtung falls dir member alignment nichts sagt...
-
hansi-dernetzwerktroll schrieb:
du machst eine struct mit deinen daten, also alle variablen, so wie sie kommen in der Reihenfolge in der struct. dann alloziierst du speicher in der größe einer struct. liest in den speicher (pointer evtl. nach (unsigned)char casten) die daten aus dem netzwerk ein. dann castest du den pointer zum pointer-typ der struct. und tada!
achtung: im compiler member alignment ausschalten, weil der compiler sonst deine Variablen auf 2/4/x-Byte grenzen ausrichtet.
das geht nur bei strings mit gleicher länge
-
Du könntest das wie folgt
#include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { char data[] = {0x05, 0xA0, 0x78, 0x48, 0x69, 0x00, 0x00 }; char* ptr = data; unsigned char zahl1; short zahl2; zahl1 = *reinterpret_cast<unsigned char*>(ptr); ptr += sizeof(zahl1); zahl2 = *reinterpret_cast<short*>(ptr); ptr += sizeof(zahl2); string str(ptr); ptr += str.size() + 1; // das terminierende Nullzeichen nicht vergessen... cout<<"Zahl1: "<<static_cast<int>(zahl1)<<endl; cout<<"Zahl2: "<<zahl2<<endl; cout<<"Str : "<< str<<endl; }lesen...
Analog sollte das auch für andere Datentypen funktionieren...
Achtung: Du musst allerdings auf die Endianess achten!
Edit: Beispiel angepasst...
Edit 2: Besser so? :p
-
ProgChild schrieb:
Achtung: Du musst allerdings auf die Byte-Endianess achten!
*Byte-*Order oder Endianess. Gemixt mag das nicht werden!

-
ne schrieb:
das geht nur bei strings mit gleicher länge
du meist, wenn der die nutzdaten, variable länge haben? ich weiß nicht wie es performance mäßig aussieht, aber man könnte entweder das maximum alloziieren, und bis zu einem delimiter vom socket lesen, oder speicher dynamisch allozieren, nachdem, man die länge der nutzdaten vorher empfangen hat.