Serialisieren oder nicht



  • akoww schrieb:

    Und jetzt wollte ich einmal wissen ob ganze Zahlen (int/long/...) auf allen gängigen/modernen Plattformen gleich dargestellt werden oder nicht.
    Könnte ich also alle diese Daten einfach direkt durch den Socket schicken oder müsste ich sie Serialisieren damit es zu keinen Problemen kommt?

    Die Darstellung der Daten ist maschinenspezifisch, sowohl die Größe als auch die Bytereihenfolge.

    Daher werden derartige Daten gängigerweise in "Network Byte Order" (Big-Endian) übertragen. Die gängigen Sockets-Implementierungen bringen hierfür Makros mit, die von Host- in Netzwerk-Bytereihenfolge und zurück wandeln können. Wenn du zusätzlich noch Datentypen fester Größe (uint32_t usw.) verwendest, wird es keine Probleme geben.

    #include <arpa/inet.h>
    
    uint32_t htonl(uint32_t hostlong);
    
    uint16_t htons(uint16_t hostshort);
    
    uint32_t ntohl(uint32_t netlong);
    
    uint16_t ntohs(uint16_t netshort);
    

    Alternativ kannst du natürlich auch in ein Format deiner Wahl serialisieren.



  • Danke cooky451,

    Das mit dem int/long war nur ein Beispiel. Das mit dem little-endian hingegen ist das, was mir wichtig ist. Ich schätze aber mal, wenn ich auf x86/arm Architekturen arbeite dann ist es egal, oder?



  • akoww schrieb:

    Das mit dem int/long war nur ein Beispiel. Das mit dem little-endian hingegen ist das, was mir wichtig ist. Ich schätze aber mal, wenn ich auf x86/arm Architekturen arbeite dann ist es egal, oder?

    Jein. Während x86 tatsächlich immer Litte-Endian ist, lassen sich viele ARM-SoCs auch für Big-Endian konfigurieren.



  • danke sahnemann,

    schade, dann muss ich wohl oder übel serialisieren.



  • Beispiel:
    Bei 64-Bit Linux ist ein long auch 64-Bit groß
    Bei 64-Bit Windows hat ein long nur 32-Bit.

    Bei den 32-Bit Versionen ist long auch 32-Bit



  • DirkB schrieb:

    Bei 64-Bit Windows hat ein long nur 32-Bit.

    Das ist so nicht ganz korrekt, sizeof(long) ist auch auf Windows64 8. Du hast wahrscheinlich eine 32 Bit exe getestet.



  • Und du hast es wahrscheinlich gar nicht getestet. 🙂

    In the LLP64 data model, only pointers expand to 64 bits; all other basic data types (integer and long) remain 32 bits in length.

    Quelle: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384083(v=vs.85).aspx



  • Eine frage hätte ich doch noch: Gibt es schon fertige Funktionen/Makro die ein uint8_t in Network Byte Order umwandeln?

    edit:
    vergesst es 😃



  • Was soll die Funktion denn machen? Das Byte mit sich selbst swappen?

    @EinGast Ich hätte schwören können sizeof(long) ist 8! Na ja, sorry DirkB, hast recht gehabt.



  • das ist ein grund weshalb die meisten konsolenprogrammierer primitive datentypen selbst definen bzw typedeffen. dank stdint.h kann man das sogar ziemlich einfach, da ist standardiziert ist. dann kann man sich sicher sein, dass ein int32_t immer ein int32_t ist und ein uint_fast16_t dann auch der schnellst moegliche uint ist von mindestens 16bit.

    endianes muss man sich auch gut ueberlegen ob das noetig ist, wenn eine software fuer vorher bekannte systeme gemacht wird, z.b. pc,ios und android, kann man sich die frickelei sparen.



  • Hinweis: Microsoft wollte dieses Problem mit .NET lösen und hat es teilweise geschafft. Hier sind auch die Datentypen (z.B. int) statische Klassen,
    die auf jeder Platform eigenständig interpretiert werden. Nützt aber wenig, weil Microsft-abhängig und evtl. ein Umstieg auf C# erforderlich wird.


Anmelden zum Antworten