Den Standardweg (Da ist übrigens ein Fehler drin: SocketOptionName.Broadcast muss auf 1 statt auf 0 gesetzt werden), wie man Broadcasts versendet, hatte auf meinem Rechner zur Folge, dass nur ein einziger Netzwerkadapter die Broadcasts versendete. Dies war nicht das, was ich wollte, denn es war auch noch ein VMWare-Adapter.
Nach etwas Probieren fand ich heraus, dass statt IPAddress.Broadcast besser IPAddress.Parse(…) mit der richtigen Broadcast-IP für das jeweilige Netz genommen werden sollte. Ich suchte mir also das nötige Zeug von zwei Artikeln zusammen: Ich frage nun alle Netzwerkkarten ab, die IP können, kalkuliere deren Broadcast-IP und versende dann das Broadcast-Paket für jedes Netz einzeln in einer Schleife. Nun bekommen alle Netze meinen Broadcast, wie gewünscht!
Wer den Quelltext sehen will, sollte den Artikel weiterlesen!
private static void SendBroadcastPacket(int destinationPort, byte[] content) { var NetworkInfo = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"); ManagementObjectCollection MOC = NetworkInfo.Get(); foreach (ManagementObject mo in MOC) { var adapterAddresses = (string[])mo["IPAddress"]; var adapterSubnetMasks = (string[])mo["IPSubnet"]; if (adapterAddresses.Count() > 0 && adapterSubnetMasks.Count() > 0) { try { IPAddress broadcastIpForAdapter = GetBroadcastAddress(IPAddress.Parse(adapterAddresses[0]), IPAddress.Parse(adapterSubnetMasks[0])); SendBroadcastPacketToBroadcastIp(broadcastIpForAdapter, destinationPort, content); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } } } private static IPAddress GetBroadcastAddress(IPAddress ipAddress, IPAddress subnetMask) { byte[] ipAdressBytes = ipAddress.GetAddressBytes(); byte[] subnetMaskBytes = subnetMask.GetAddressBytes(); if (ipAdressBytes.Length != subnetMaskBytes.Length) throw new ArgumentException("Both IP address and subnet mask should be of the same length"); var result = new byte[ipAdressBytes.Length]; for (int i = 0; i < result.Length; i++) result[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255)); return new IPAddress(result); } private static void SendBroadcastPacketToBroadcastIp(IPAddress broadcastIp, int destinationPort, byte[] content) { Socket sock = null; try { var destinationEndpoint = new IPEndPoint(broadcastIp, destinationPort); sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); sock.SendTo(content, destinationEndpoint); } finally { if (sock != null) { sock.Close(); } } }
Hi,
danke für den Tipp
Ich habe da einen kleinen Fehler entdeckt:
Die Methode adapterAddresses.Count() gibt’s nicht. Man sollte hier adapterAddresses.Length verwenden.
Beste Grüße
Alex
Hallo Alex,
es freut mich, dass ich dir helfen konnte mit meinem Artikel!
Du hast mit deiner Aussage natürlich insofern recht, als dass ich keine usings im Artikel geschrieben habe.
Count() ist eine Extension-Methode, die mit Linq kommt und sich im Namensraum System.Linq versteckt.
Gruß
Fabian
Hi,
ich weiß dass das hier schon wieder ein paar Monate alt ist, aber trotzdem habe ich eine Frage dazu:
Wenn ich einen Broadcast mit einem speziellen Content sende, auf den nur bestimmte Geräte im Netzwerk reagieren, schicken diese ja eine Antwort. Wie kann ich aus dieser Antwort die IP-Adresse des jeweiligen Gerätes herausfiltern? Ich möchte so die IP-Adressen bestimmter Geräte herausfinden, da nur diese auf die Broadcastanfrage reagieren.
Gruß Kai
Hallo Kai,
schau dir mal UdpClient.Receive() an:
http://msdn.microsoft.com/de-de/library/system.net.sockets.udpclient.receive.aspx
Du bekommst die eigentlichen Daten als Rückgabe und die IP hast du in der REF-Variable stehen. Das sollte dir helfen!
Viel Spaß beim broadcasten!
Gruß
Fabian
Hallo Fabse,
das hört sich vielversprechend an. Wird gleich mal getestet. Vielen Dank für deine Antwort.
Gruß Kai
Hallo Fabian,
ich habe da leider immernoch Probleme. Wäre nett wenn du mir helfen könntest.
Folgendes Problem:
Ich sende einen UDP-Broadcast an Adresse 255.255.255.255 an Port 8888 mit dem Befehl “hallo”.
Daraufhin gibt das gewünschte Gerät im Netzwerk die Antwort “OK” zurück und zwar an den Port, der zum Senden des Broadcast automatisch geöffnet wurde (z.B. 50742).
Ich kann zwar das “OK” empfangen, aber nur über den Socket, der zum Senden des Broadcasts verwendet wurde. Und dort komme ich einfach nicht an die IP-Adresse des Geräts ran.
Um deine Empfehlung ( UdpClient.Receive() ) zu verwenden, muss ich doch aber wissen, auf welchen Port dieser UdpClient hören soll?!
Wie kann ich das lösen?
Gruß Kai