TCP Datenübertragung mit ZUSI

Erste Ansprechstelle für technische Fragen der Add-On Bastler, Fragen/Umgang mit den Zusi 2-Editoren
Antworten
Nachricht
Autor
Benutzeravatar
Jens Haupert
Beiträge: 4927
Registriert: 23.03.2004 14:44:34
Aktuelle Projekte: http://www.zusidisplay.de
Wohnort: Berlin
Kontaktdaten:

TCP Datenübertragung mit ZUSI

#1 Beitrag von Jens Haupert »

Hallo,
ich habe mir für EBuLa einen eigenen kleinen Server geschrieben, da der geplante noch nicht zur verfügung steht.
Klappt jetzt auch wunderbar, nur eine Frage hätte ich da noch:

Zusi überträgt die Daten ja als Byte-Array. In der Doku wird die Umwandlung in den Single Typ an einem Codebeispiel in Delphi gezeigt.
Jetzt weiß ich leider nicht wie man das mit C-Sprachen macht? ?(

Bin da im Moment etwas ratlos. Kann mir jemand auf die Sprünge helfen. Danke im Voraus.

MfG Jens

Benutzeravatar
Roland Ziegler
Beiträge: 5508
Registriert: 04.11.2001 22:09:26
Wohnort: 32U 0294406 5629020
Kontaktdaten:

#2 Beitrag von Roland Ziegler »

Zuerst ist festzuhalten, dass keinerlei Marshaling verwendet wird, die Datenrepräsentation im Socket-Stream gleich der auf dem jeweiligen Prozessor ist, in diesem Falle also "Little Endian", d.h. least significant byte first. Wir hoffen mal, das auch .net sich daran hält, aber ausprobiert habe ich es noch nicht. (Java erzeugt ja bei allen gemarshalten Daten "Big Endian"). Bei little Endian bieten sich simple Type-Casts zur Konvertierung an. Das explizite Umkopieren wie in dem Delphi-Beispiel sollte man sich in C, C++ und C# schenken können. Ansonsten denke ich, dass es hier für C, C++ und C# durchaus unterschiedlich ausgeprägte Lösungen gibt.

In C könnte man den direkten Pointer-Zugriff mit einem Type-Cast auf den Datenpuffer nutzen, der für den TCP-Socket benutzt wird.

In C++ würde man vielleicht ein Stream-Klasse einsetzen oder sich eine selber schreiben, die den Socket-Puffer betreibt, und auch dann wieder mit direktem Pointer-Zugriff arbeiten, dieses aber pseudo-typsicher als Methoden der Stream-Klasse kapseln.

In C# würde man wohl die NetworkStream-Klasse nutzen wollen, und darauf die Methoden des binären Lesens und Schreibens anwenden.


Edit: Code-Beispiel in C# mit vereinfachend MemoryStream statt NetworkStream:

Code: Alles auswählen

            // Sendeseite
            float myfloatout = 1.2345f;

            MemoryStream osm = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(osm);
            writer.Write(myfloatout);

                
            // Empfangsseite, Puffer vereinfacht aus Sendeseite übernommen    
            MemoryStream ism = new MemoryStream(osm.GetBuffer());
            BinaryReader reader = new BinaryReader(ism);

            float myfloatin = reader.ReadSingle ();
Zuletzt geändert von Roland Ziegler am 20.08.2004 21:54:37, insgesamt 1-mal geändert.

Benutzeravatar
Jens Haupert
Beiträge: 4927
Registriert: 23.03.2004 14:44:34
Aktuelle Projekte: http://www.zusidisplay.de
Wohnort: Berlin
Kontaktdaten:

#3 Beitrag von Jens Haupert »

Hallo,
funktioniert wunderbar. :D Danke!

MfG Jens

Benutzeravatar
Roland Ziegler
Beiträge: 5508
Registriert: 04.11.2001 22:09:26
Wohnort: 32U 0294406 5629020
Kontaktdaten:

#4 Beitrag von Roland Ziegler »

Prima.

Diese .Net BinaryReader/Writer sind ja nichts anderes als Adpater zur Kapselung des direkten Type-Cast. Die sollte man für so etwas immer einsetzen, auch für Integer, also

Code: Alles auswählen

            MemoryStream ism = new MemoryStream(buffer);
            BinaryReader reader = new BinaryReader(ism);
            ushort myshortin = reader.ReadUInt16();
und nicht etwa

Code: Alles auswählen

            ushort myshortin = buffer[0] + buffer[1]*256;
Letzteres wäre dann doch sehr ineffektiv.

Antworten