Hallo Leute,
Ich versuche ein UDP-Packet zu empfangen.
Es wird ein UDP-Multicast an das lokale Subnetz geschickt und auf eine Antwort gewartet:
String data = "HALLO";
UdpClient client = new UdpClient();
IPEndPoint qwer = new IPEndPoint(IPAddress.Parse("192.168.10.255"), 4712);
client.EnableBroadcast = true;
client.Connect(qwer);
byte[] asdf = Encoding.UTF8.GetBytes(data);
client.Send(asdf, asdf.Length);
int port = ((IPEndPoint)client.Client.LocalEndPoint).Port;
IPEndPoint receive = new IPEndPoint(IPAddress.Any, port);
byte[] received = client.Receive(ref receive);
Console.WriteLine(Encoding.UTF8.GetString(received));
Console.Read();
Das UDP-Packet wird auf dem Client empfangen (Wireshark auf dem Client zeigt das Paket an),
jedoch empfängt die C#-Software das Packet nicht. Der Port des LocalEndpoint stimmt auf dem Server und Client überein.
Wenn ganz oben anstatt "192.168.10.255" die IP-Adresse des Servers "192.168.10.42" verwendet wird, funktioniert auch das Empfangen des Packetes.
Wo liegt hier der Fehler?
mfg,
Dexter
Programmierer sind Maschinen die Koffein in Quellcode umsetzen.
Ich denke das ist ein Zeitproblem. Das UDP Paket kommt an, bevor die Receive Methode aufgerufen wird. Hab das Empfangen mal in einen extra Thread gesetzt.
private static int _port = 4712;
private static AutoResetEvent _waitHandle;
internal static void Test()
{
_waitHandle = new AutoResetEvent(false);
new Thread(Listen).Start();
_waitHandle.WaitOne();
String data = "HALLO WELT";
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPAddress broadcast = IPAddress.Parse("192.168.178.255");
IPEndPoint ep = new IPEndPoint(broadcast, _port);
s.SendTo(Encoding.ASCII.GetBytes(data), ep);
}
private static void Listen()
{
bool done = false;
UdpClient listener = new UdpClient(_port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _port);
try
{
_waitHandle.Set();
while (!done)
{
byte[] bytes = listener.Receive(ref groupEP);
Console.WriteLine("Received broadcast from {0} :\n {1}\n", groupEP.ToString(), Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
listener.Close();
}
}
Ich habe gerade selbst mehrere Stunden mit genau diesem gleichen Problem verbracht. Den Receiver in einen eigenen Thread zu packen hat leider auch nichts geändert.
Gerade bin ich drauf gekommen: Ich habe meine Firewall deaktiviert... Dann kommt auch die Unicast-Antwort auf die Broadcast-Pakete nicht nur in Wireshark an, sondern auch in meiner App.
Jetzt muss ich noch rausfinden, wie ich die Firewall elegant tunnele, ohne auf jedem Rechner erst eine Ausnahmeregel zu erstellen.
UDP hole punching - ganz typischer Fall zB für Online-Spiele oder Audio-Kommunikation.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo,
Wenn ganz oben anstatt "192.168.10.255" die IP-Adresse des Servers "192.168.10.42" verwendet wird, funktioniert auch das Empfangen des Packetes.
Wo liegt hier der Fehler?
am "client.Connect" - weglassen und stattdessen den IPEndPoint beim Senden verwenden.
UDP an sich ist verbindungslos, Connect hat eine sehr spezielle Funktion (s. MSDN) und wird äußerst selten notwendig.
Das Problem ist, dass meine Gegenstelle nicht umprogrammiert werden kann. Außerdem soll es nach Möglichkeit auch ohne ein weiteres Endgerät (wie eben der Server, der den Verbindungsaufbau initiiert) funktionieren.
Lustigerweise funktioniert es mit der originalen Herstellersoftware für das Gerät, was ich anspreche. Da brauche ich an der Firewall nichts zu verändern. Bei meinem eigenen Programm eben schon... Laut Wireshark schickt das originale Programm aber auch nichts weiter raus als ich es tue.