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.
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 - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.
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.
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.
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();
// ...
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();
Never trust a running system.
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 - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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.