Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
UDP Mehrere Daten gleichzeitig senden und empfangen
dev.pr
myCSharp.de - Member



Dabei seit:
Beiträge: 22
Herkunft: Berlin

Themenstarter:

UDP Mehrere Daten gleichzeitig senden und empfangen

beantworten | zitieren | melden

Hallo liebe Community,
ich habe ein kleines Problem, ich bin gerade dabei ein kleines Spiel zu schreiben was man zu 2 über UDP spielen kann. Ja ich weiß auch das UDP nicht die beste Lösung ist aber meine Schule möchte es so.
Ich habe eine Verbindung erfolgreich aufgebaut und bekomme auch erfolgreich daten gesendet und empfangen, jedoch sind diese dann verwurschtelt (nehme ich an). Mein Ziel ist es das wenn ich meine PictureBox bewege, sie sich auf dem anderen Bildschirm auch bewegt, also quasi die Daten von Spieler1 an Spieler2 senden und von Spieler2 an Spieler1. Wenn ich nur die Y-Koordinate sende klappt alles, aber sobald ich die x-koordinate mit sende klappt es nicht mehr. Hier mal mein Code:


private void UDPSENDER_Tick(object sender, EventArgs e)
        {

            //ALG 
            // 0 = X-Wert des Spieler1
            // 1 = Y-Wert des Spieler1
            // 2 = Coin-Koordinate X
            // 3 = Coin-Koordinate Y
            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
            byte[] msg = new byte[1500];
            if(udpalg == 0)
            {
                msg = enc.GetBytes(x.ToString());
                sck.Send(msg);
                udpalg++;
            }
            else if (udpalg == 1)
            {
                msg = enc.GetBytes(y.ToString());
                sck.Send(msg);
                udpalg++;
            }
            else if (udpalg == 2)
            {
                msg = enc.GetBytes(pictureBox1.Location.X.ToString());
                sck.Send(msg);
                udpalg++;
            }
            else if (udpalg == 3)
            {
                msg = enc.GetBytes(pictureBox1.Location.Y.ToString());
                sck.Send(msg);
                udpalg = 0;
            }
        }

Da werden die Daten gesendet,
hier werden sie empfangen:


private void MessageCallBack(IAsyncResult aResult)
        {
            try
            {
                int size = sck.EndReceiveFrom(aResult, ref epRemote);
                if (size > 0)
                {
                    byte[] receivedData = new byte[1464];
                    receivedData = (byte[])aResult.AsyncState;
                    ASCIIEncoding eEncoding = new ASCIIEncoding();
                    string receivedMessage = eEncoding.GetString(receivedData);
                    //ALG 
                    // 0 = X-Wert des Spieler1
                    // 1 = Y-Wert des Spieler1
                    // 2 = Coin-Koordinate X
                    // 3 = Coin-Koordinate Y
                    if (udpalg == 0)
                    {
                        S2X = Convert.ToInt32(receivedMessage);
                    }
                    else if (udpalg == 1)
                    {
                        S2Y = Convert.ToInt32(receivedMessage);
                    }
                    else if (udpalg == 2)
                    {
                        Coinx = Convert.ToInt32(receivedMessage);
                    }
                    else if (udpalg == 3)
                    {
                        Coiny = Convert.ToInt32(receivedMessage);
                    }
                    S2.Location = new Point(S2X, S2Y);
                    pictureBox1.Location = new Point(Coinx, Coiny);


                }

                byte[] buffer = new byte[1500];
                sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

was mache ich falsch?

LG
Never trust a running system.

Youtube
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16112

beantworten | zitieren | melden

UDP ist für Spiele und Video-Übertragung i.d.R. besser als TCP.
Bei solchen Anwendungen stört es nicht, wenn ein Datenpaket fehlt und ein Nachsenden eines Datenpakets bringt ja in den meisten Szenarien solcher Anwendungen dann auch nichts mehr.

"Klappt nicht" ist keine akzeptable Fehlermeldung in einem Forum. Keiner hat hier lust zu raten.
Bitte beachte [Hinweis] Wie poste ich richtig? insbesondere Punkt 5.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
dev.pr
myCSharp.de - Member



Dabei seit:
Beiträge: 22
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo, danke erst einmal für die schnelle Antwort.

Also so wie das Programm da steht passiert folgendes:

Die X Position von S2 bewegt sich, jedoch nicht die Y Position und der Coin bewegt sich komplett garnicht.

Ich habe mal geschaut, die Picturebox S2 nimmt alle Werte an, dass heißt ich sende von S1 die X und Y werte und von dem Coin(ist auch eine Picturebox) auch die X und Y Werte und beim empfangen greift sich S2 alle Werte und springt dann immer zwischen 4 Werten rum, ich hoffe ich konnte mich gut ausdrücken.

nochmal zusammengefasst S2 denkt das S1 XundY Werte und Coin XundY Werte für S2 als X-Wert gedacht ist
Never trust a running system.

Youtube
private Nachricht | Beiträge des Benutzers
unconnected
myCSharp.de - Member

Avatar #avatar-3200.jpg


Dabei seit:
Beiträge: 862
Herkunft: Oerlinghausen/NRW

beantworten | zitieren | melden

Hallo,

ich denke du vergisst in deiner MessageCallback Methode udpalg zu inkrementieren.
Ist aber auch gefährlich, denn wenn ein Udp Packet nicht ankommt oder der sender neu gestartet wird, kommt deine Logik vollkommen durcheinander.
private Nachricht | Beiträge des Benutzers
dev.pr
myCSharp.de - Member



Dabei seit:
Beiträge: 22
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo, habe es inkrementiert, und ja es kommt sehr schnell durcheinander.

Kennt jemand noch eine andere möglichkeit so etwas zu regeln?

danke erstmal trotzdem für die Hilfe.

LG
Never trust a running system.

Youtube
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Warum sendest du denn nicht alle 4 Werte in einer Nachricht?
Und besser wäre es auch, die Werte direkt binär zu verschicken anstatt als Strings. Schau dir dazu mal die Klassen BinaryWriter und BinaryReader an.
private Nachricht | Beiträge des Benutzers
dev.pr
myCSharp.de - Member



Dabei seit:
Beiträge: 22
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo, weil ich nicht weiß wie ich diese 4 Werte dann wieder trennen soll wenn ich sie erhalt, kannst du mir sagen wie man sowas trennt?

ja werde ich mir mal anschauen danke
Never trust a running system.

Youtube
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Du brauchst diese nicht trennen, da du diese einfach der Reihe nach mit dem BinaryReader aus dem Stream liest (die Grunddatentypen wie int sind binär immer gleich groß):


var binaryReader = new BinaryReader(message);
int x = binaryReader.ReadInt32();
int y = binaryReader.ReadInt32();
// ...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am .
private Nachricht | Beiträge des Benutzers
dev.pr
myCSharp.de - Member



Dabei seit:
Beiträge: 22
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo,

Werde es gleich mal ausprobieren und mal schauen ob es klappt, vielen dank!
Never trust a running system.

Youtube
private Nachricht | Beiträge des Benutzers
dev.pr
myCSharp.de - Member



Dabei seit:
Beiträge: 22
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Hallo, habe es nicht ganz hinbekommen, deine Variable (Message) habe ich durch receivedMessage ersetzt, hat als string nicht funktioniert und als integer auch nicht. Und beim senden klappt es auch noch nicht so ganz, wenn ich die daten empfange mache ich glaube ich noch einen fehler.


                    byte[] receivedData = new byte[1464];
                    receivedData = (byte[])aResult.AsyncState;
                    ASCIIEncoding eEncoding = new ASCIIEncoding();
                    string receivedMessage = eEncoding.GetString(receivedData);
                    int message = Convert.ToInt32(receivedMessage, 2);
                    var binaryReader = new BinaryReader(message);
                    int x = binaryReader.ReadInt32();
                    int y = binaryReader.ReadInt32();
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dev.pr am .
Never trust a running system.

Youtube
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16112

beantworten | zitieren | melden

Willst Du den Helfern nicht ein paar mehr Informationen zukommen lassen als "klappt nicht" und "funktioniert nicht"?
[Hinweis] Wie poste ich richtig? Punkt 5
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4140

beantworten | zitieren | melden

Hallo dev.pr,

du solltest dich mal intensiver mit den (Standard-)Datentypen auseinandersetzen.
Der BinaryReader erwartet ein Byte-Array, und das hast du doch schon als receivedData vorliegen, also kannst du dieses direkt übergeben (das ganze Konvertieren ist also überflüssig).

PS: Außerdem ist das Initialisieren des Byte-Arrays sinnfrei, da du es ja in der nächsten Zeile wieder neu zuweist. Es reicht also


byte[] receivedData = (byte[])aResult.AsyncState;
Und da BinaryReader die IDisposable-Schnittstelle implementiert, müßte man dann korrekterweise noch Dispose() aufrufen, bzw. eleganter mittels


using (var binaryReader = new BinaryReader(receivedData))
{
    int x = binaryReader.ReadInt32();
    int y = binaryReader.ReadInt32();
}
Und das selbe mußt du dann natürlich auch beim Senden umsetzen.
private Nachricht | Beiträge des Benutzers