C# - Byte Array in Double wandeln

Hoschi89

Grünschnabel
Hi community,

ich habe derzeit ein Programm (fertig vorgegeben, nicht zu ändern), welches mir über eine TCP-Verbindung double oder ganzzahlige Werte verschickt.

Ich programmiere die Emfpängerseite, auf der ich die Daten in ein byte-Array einlese und dieses dann in einer Console ausgeben möchte.
Problem dabei ist, dass die empfangenen DAten ja zunächst wieder in einen Double konvertiert werden müssen.

Derzeit habe ich es so probiert:
PHP:
namespace Empfänger
{
    class TCP_Server

    {
             static void Main(string[] args)
        {


           byte[] buffer = new byte[32]; //Empfangsbuffergröße 32 Byte
               
            var TS_IP = IPAddress.Parse("127.0.0.1");  // Einstellen der TS Client-IP. 127.0.0.1 eingeben für lokale Testzwecke.
            int TS_Port = 5480;

            TcpListener tcpServer = new TcpListener(TS_IP, TS_Port); //TCP-Empfangen auf IP: "TS_IP" Port: "TS_Port" 

                //TCP-Server initialisieren
                tcpServer.Start();

                Console.WriteLine("TCP-Empfänger gestartet auf IP: {0} und Port: {1}", TS_IP, TS_Port);



                using (Socket socket = tcpServer.AcceptSocket())
                {
                    while (true)
                    {
                        if (socket.Available > 0)
                        {
                            socket.Receive(buffer); //Empfangen in Buffer
                            


                            double d = BitConverter.ToDouble(buffer, 0);
                            Console.WriteLine("Geschwindigkeit :{0}", d);
                            }
                          
                            Console.BackgroundColor = ConsoleColor.Black;
                            Console.WriteLine("Daten empfangen.");
                        }
                        else
                       Thread.Sleep(10);
                    }
                }

Es soll dabei z.B. die Geschwindigkeit eines Objekts übertragen werden.
Wenn diese beispielsweise 8,0000 m/s beträgt, gibt mir meine Console jedoch 4.079.....E320 aus. Warum?


Der nächste Schritt wäre dann, dass ich verschiedene Datentypen (double, byte, long) verschicke, diese in das Array lade und dann ausgeben lasse. Wie könnte ich das denn realisieren?


Viele Grüße

Hoschi
 
Hi und Willkommen bei tutorials.de

hast du mal überprüft, ob die Byte dieselben sind, wie versendet werden (sollen)?
Wie wird auf Senderseite umgewandelt?
 
Zuletzt bearbeitet:
Hi.

Also erstmal solltest du prüfen wieviel Bytes du überhaupt empfangen hast. (ist es überhaupt ein vollständiger Double Wert?)

In welcher Sprache ist der Server geschrieben, bzw. was versteht der Server unter einem Double? Ein 64bit IEEE 754 Typ?

Sendet der Server zufällig in Netzwerk Byte Order? Dann müßtest du die Bytes umkehren.

\edit: Außerdem, wie erkennst du denn ob der Server einen Double oder einen Ganzzahlwert schickt? Da müßte es ja ein Protokoll geben.

Gruß
 
Hi,

schonmal vielen Dank für eure Antworten.
Mittlerweile klappt es auch, hab das Array auf 8 Byte Größe gesetzt und mal die Littleendian/BigEndian Sache ausprobiert.
PHP:
 {

                            if (BitConverter.IsLittleEndian)
                                Array.Reverse(buffer);

                            double d = BitConverter.ToDouble(buffer, 0);
                            Console.WriteLine("Geschwindigkeit :{0}", d.ToString());
                        }

Wie wird auf Senderseite umgewandelt?
Das weiß ich leider nicht. Ich habe ein Programm, bei dem ich nur einige Parameter verändern kann( z.B. ob meine ausgewählte Variable den Typ Double oder Word oder long besitzt). Daraufhin wird dies über eine Tcp Verbindung geschickt und ich versuche es auszulesen.

Also erstmal solltest du prüfen wieviel Bytes du überhaupt empfangen hast
Wie kann ich das denn in C# und VS 2010 umsetzen? Hatte es schon mit int i sizeof(buffer) probiert, funktioniert aber leider nicht.



Wenn ich jetzt von meinem Sender aus verschiedene Typen versende(Double und Word z.B.) wie könnte ich die denn in meinem Empfänger wieder auftrennen um das jeweils benötige Encoding zu implementieren?

Gruß Hoschi
 
Der Rückgabewert von Receive ist die empfangene Byteanzahl.

Es könnte übrigens passieren, dass du einmal nur zB. 3 Byte und erst beim nächsten Receive die restlichen 5 Byte bekommst. Da sollte man noch was machen
(Schleife, solange keine 8 Byte und kein Fehler...)


Zum Unterscheiden von den Variablentypen:
Wenn der Sender wirklich nur die rohen Byte sendet und du daran nichts ändern kannst
wirds ziemlich unmöglich, durch die Byte den Typ zu bestimmen.
 
Hi,

ok, dann versuche ich es mal mit dem return Receive.

Die einzigen Infos die ich über den "Sender" noch habe sind folgende:

Das Programm sendet binäre Pakete mit genau der aufsummierten
Bytelänge der Datentypen.
Die Pakete werden dabei byteweise gepackt. Darauf müssen Sie unbedingt
achten (Compilereinstellungen)

Kann man mit diesen Infos noch was anfangen? Vorallem das mit dem "byteweise gepackt"?
 
Zuletzt bearbeitet:
Der Rückgabewert von Receive ist die empfangene Byteanzahl.

Hab mal versucht
PHP:
return Socket.Receive(buffer);
auszugeben, bekomme aber die Fehlermeldung:
Da "Empfänger.TCP_Server.Main(string[])" "void" zurückgibt, darf auf ein Rückgabeschlüsselwort kein Objektausdruck folgen"

Welchen Typ muss ich denn der main-Methode zuordnen damit das klappt?
Derzeit sieht es so aus:
PHP:
namespace Empfänger
{
    class TCP_Server
    {
        public static void Main(string[] args)
        {


Und wo sollte so eine Return-Angabe hingesetzt werden? Zum Teil bekomme ich die Fehlermeldung dass "unnereichbarer Code" vorliegt.


Gruß Hoschi
 
Hab mal versucht
PHP:
return Socket.Receive(buffer);
Das hast du völlig falsch verstanden.

Die return Anweisung würde die Methode ja sofort beenden.

Du solltest den Rückgabewert der Receive Methode prüfen, ungefähr so:
C#:
int read = 0;
do {
  read += server.Receive(buf, read, BYTES_TO_READ - read, SocketFlags.None);
} while (read < BYTES_TO_READ);
\edit: Du kannst aber auch gleich eine andere Variante von Receive verwenden, die sicherstellt, dass eine bestimmte Anzahl von Bytes gelesen wird:
Welchen Typ muss ich denn der main-Methode zuordnen damit das klappt?
Die main Methode muss einen bestimmten Prototyp haben, man kann den Rückgabetyp nicht einfach ändern.
Zum Teil bekomme ich die Fehlermeldung dass "unnereichbarer Code" vorliegt.
Klar, der Code nach der return Anweisung wird ja auch nie ausgeführt werden - return verläßt die Methode.
Das Programm sendet binäre Pakete mit genau der aufsummierten
Bytelänge der Datentypen.
Die Pakete werden dabei byteweise gepackt. Darauf müssen Sie unbedingt
achten (Compilereinstellungen)
Kann man mit diesen Infos noch was anfangen? Vorallem das mit dem "byteweise gepackt"?
Anscheinend sendet der Server nicht einfach Double Werte, sondern eine Struktur bestehend aus mehreren Datentypen. Mit dem "byteweise gepackt" ist gemeint, dass die Daten ohne Lücken direkt hintereinander stehen.

Du solltest also nicht nur einen Double einlesen, sondern ein vollständiges Paket. Daraus kannst du dann die einzelnen Werte extrahieren.

Gruß
 
Zuletzt bearbeitet:
So nachdem das Einlesen einzelner Datentypen soweit gut geklappt hat, muss ich jetzt hinbekommen, dass ich verschiedene Datentypen (dabei handelt es sich nur um byte und float Werte) auslesen kann.

Du solltest also nicht nur einen Double einlesen, sondern ein vollständiges Paket. Daraus kannst du dann die einzelnen Werte extrahieren.

Wie kann ich den anstelle eines Datentyps ein vollständiges Paket einlesen?
Ich wollte so vorgehen, dass ich wieder ein Array befülle und dann im Anschluss sage, dass die ersten Werte die ankommen z.B. float Werte sind und die nächsten byte Werte.

Ich habe gesehen, dass es in C (also nich C#) einen struct-Befehl gibt, mit dem man direkt eine Struktur aus verschiedenen Datentypen senden/empfangen kann.
Bsp:
PHP:
struct sSendData
{
float v_max;
byte Tastendruck

etc...
}

gibt es sowas denn auch in C#? Die MSDN Hilfe hat mir da leider nicht viel weitergeholfen. Wäre natürlich um einiges leichter, als zunächst ein Array zu definieren.

Viele Grüße
 
Zurück