Wake on Lan Paket versenden

  • C#

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Fakiz.

    Wake on Lan Paket versenden

    Guten Abend,
    ich versuche an meinen PC ein Wake on Lan Paket zu senden. Das Problem ist das daß Paket nicht bei meinem Rechner ankommt. Kann mir hier vieleicht jemand weiterhelfen?

    WakeOnLan

    C#-Quellcode

    1. static void WakeOnLan(string strMac)
    2. {
    3. byte[] mac = Encoding.ASCII.GetBytes(strMac);
    4. List<Byte> magicPacket = new List<Byte>();
    5. for (int i = 0; i < 6; i++)
    6. magicPacket.Add(0xFF);
    7. for (int i = 0; i < 16; i++)
    8. magicPacket.AddRange(mac);
    9. IPAddress ip = IPAddress.Broadcast;
    10. int port = 7;
    11. // Sende WOL Paket
    12. using (UdpClient udp = new UdpClient()) {
    13. udp.Connect(ip, port);
    14. udp.Send(magicPacket.ToArray(), magicPacket.Count);
    15. }
    16. // Event feuern
    17. SendMagicPacket(ip, port, mac, magicPacket.ToArray());
    18. }

    Hi,

    für MAC-Adressen kannst Du auch die PhysicalAddress-Klasse benutzen. Diese hat eine Methode GetAddressBytes. Dann kannst Du via UDP die Pakete auch direkt senden, ohne vorher Connect aufzurufen. Dazu gibt es eine Überladung mit IPEndPoint.
    btw: Statt einer List<byte> würde ich direkt ein byte[] füllen, aber gut, das ist Mikrooptimierung.
    Dann: Stimmt der komplette EndPoint samt Port? Du sendest das eben an die Broadcast-Adresse, nicht an einen spezifischen Host (bzw. deinen PC). Was ist, wenn Du mal direkt die lokale IP Deines PCs verwendest? Stimmt die MAC-Adresse?
    Die Implementierung des Pakets scheint soweit nämlich richtig. (Halt kein WOL-Passwort)

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    für MAC-Adressen kannst Du auch die PhysicalAddress-Klasse benutzen

    Daher kommt meine Mac-Adresse

    Was ist, wenn Du mal direkt die lokale IP Deines PCs verwendest?

    Leider das selbe Problem, es passiert nichts.

    Hast du WoL im BIOS/UEFI aktiviert? Hast du mal Port 9 probiert?

    Da bin ich mir nicht zu 100% sicher. D.h. ich hab es noch nicht geprüft da ich ich von meiner Fritzbox den PC problemlos hochfahren kann. Auch WireShark zeigt mir das WOL -Paket der Fritzbox an nur leider nicht wenn ich es von meinem Tablet sende.

    Fakiz schrieb:

    Daher kommt meine Mac-Adresse
    Warum übergibst Du dann keine Instanz und holst die Bytes aus der raus? Dann sparst Du Dir das ​Encoding.ASCII.GetBytes-Zeug.

    Nochmal: Stimmt die MAC-Adresse auch zu 100% mit der des Hosts überein? Holst Du die über ARP oder gibst Du die hardcoded mit? Notfalls einfach mal debuggen, die Daten prüfen und vielleicht auch mal Wireshark auf das Teil anwenden und die ausgehenden Pakete prüfen.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Also bei mir funktioniert folgender C#-Code, um meinen Arbeitsplatz-PC von meinem privaten Rechner aus zu starten:

    Spoiler anzeigen

    C#-Quellcode

    1. // https://www.vb-paradise.de/index.php/Thread/37834-Wake-on-Lan/
    2. // https://www.vb-paradise.de/index.php/Thread/49120-Shutdown-%C3%BCber-Mac-Adresse/
    3. using System;
    4. using System.Windows.Forms;
    5. using System.Net;
    6. using System.Net.Sockets;
    7. namespace WakeOnLAN
    8. {
    9. public partial class Form1 : Form
    10. {
    11. public Form1()
    12. {
    13. InitializeComponent();
    14. }
    15. private void button1_Click_1(object sender, EventArgs e)
    16. {
    17. WakeUp("FF-85-A9-FF-28-FF");
    18. }
    19. public const int MAC_ADDR_BYTES = 6;
    20. private const int PORT_BROADCAST = 2304;
    21. // <remarks>
    22. // Constructs and returns a magic packet for the given
    23. // MAC address.
    24. // A Magic Packet is 6 bytes of FF followed by the MAC
    25. // address 16 times.
    26. // </remarks>
    27. public static byte[] GetMagicPacket(string macAddress)
    28. {
    29. byte[] Packet = new byte[5 + 16 * MAC_ADDR_BYTES + 1];
    30. //101 => 102 Elements
    31. string[] strNumbers = macAddress.Split(new string[] { ":", ",", ";", "-" }, StringSplitOptions.RemoveEmptyEntries);
    32. byte[] macBytes = new byte[6];
    33. if (strNumbers.Length != 6)
    34. {
    35. throw new Exception("MAC Address incorrect!!!");
    36. }
    37. //Convert Numbers to Bytes and set the first 6 FF Values
    38. for (int i = 0; i <= 5; i++)
    39. {
    40. Packet[i] = 0xff;
    41. string strNumber = strNumbers[i];
    42. //Strip possible leading 0x statments
    43. if (strNumber.StartsWith("0x"))
    44. {
    45. strNumber = strNumber.Substring(2, 2);
    46. }
    47. macBytes[i] = Convert.ToByte(Int32.Parse(strNumber, System.Globalization.NumberStyles.HexNumber));
    48. }
    49. //Write the MAC address 16 times after the 6 FF values
    50. for (int j = 0; j <= 15; j++)
    51. {
    52. for (int i = 0; i <= 5; i++)
    53. {
    54. Packet[6 + j * 6 + i] = macBytes[i];
    55. }
    56. }
    57. return Packet;
    58. }
    59. //<remarks>
    60. //Sends the magic packet for a specific MAC address
    61. //</remarks>
    62. public static void WakeUp(string macAddress)
    63. {
    64. Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    65. s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
    66. byte[] Message = GetMagicPacket(macAddress);
    67. IPEndPoint IPEP = new IPEndPoint(IPAddress.Broadcast, PORT_BROADCAST);
    68. s.SendTo(Message, IPEP);
    69. }
    70. }
    71. }

    Logischerweise muss die MAC-Adresse angepasst werden!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thias“ ()

    Interessant. Ist aber eigentlich derselbe Code wie im Startpost, nur etwas länger mit einigen Dingen, die man noch verschönern könnte. :P
    Auf Socket-Basis würde ich das BTW nur bauen, wenn Du die Daten direkt in Ethernet-Frames versendest. Also SocketType.Raw und dann die Frames selber zusammenbauen. Wobei die Magic Packets ja mit jedem Protokoll versendet werden können. UDP halte ich da entsprechend auch für geeignet. Im Endeffekt nutzt Du das ja auch, aber es sollte in diesem Fall kein Unterschied zwischen den Sockets und dem UdpClient bestehen. Das Zweite ist wohl nur etwas einfacher.

    Aber den Port zu ändern könnte man immer noch probieren. Wie gesagt, ich vermute den Fehler irgendwo am IPEndPoint oder in der MAC-Adresse. WOL scheint ja aktiv zu sein.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Danke für die Hinweise - hoffe ich habe irgendwann mal Zeit mir dies genauer anzusehen - Lesezeichen ist jedenfalls gesetzt.

    Ansonsten gilt: Never change a running system! :D

    Edit: Anbei der Code von @Fakiz aus Post 9 als VB.Net-Code

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    2. WakeOnLan("FF085A9FF28FF")
    3. End Sub
    4. Public Shared Sub WakeOnLan(strMac As String)
    5. ' Byte[] MAC erstellen
    6. Dim mac As Byte() = New Byte(5) {}
    7. For i As Integer = 0 To 5
    8. mac(i) = Convert.ToByte(strMac.Substring((2 * i), 2), 16)
    9. Next
    10. ' MagicPacket Bytes
    11. Dim magicPacket As New List(Of [Byte])()
    12. For i As Integer = 0 To 5
    13. magicPacket.Add(Byte.MaxValue)
    14. Next
    15. ' 16 x MAC -Adresse zum MagicPacket hinzufügen
    16. For i As Integer = 0 To 15
    17. magicPacket.AddRange(mac)
    18. Next
    19. ' Sende WOL Paket.
    20. Dim endPoint As New IPEndPoint(IPAddress.Broadcast, 9)
    21. Using udp As New UdpClient()
    22. udp.Send(magicPacket.ToArray(), magicPacket.Count, endPoint)
    23. End Using
    24. ' Event feuern
    25. ' SendMagicPacket(endPoint.Address, endPoint.Port, mac, magicPacket.ToArray())
    26. End Sub


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thias“ ()

    Hab den Fehler entzwischen gefunden. Es lag an der Konvertierung der MAC -Adresse, die Encoder -Klasse hat mir ja den kompletten string in ein Byte -Array Konvertiert.

    Lösung:

    C#-Quellcode

    1. byte[] mac = new byte[6];
    2. for (int i = 0; i < 6; i++)
    3. mac[i] = Convert.ToByte(strMac.Substring((2 * i), 2), 16);


    Ebenso habe ich noch den Ansatz mit dem IPEndPoint übernommen und spare mir nun die Methoe .Connect().

    Hier wäre noch einmal die Vollständige Methode.
    WakeOnLan

    C#-Quellcode

    1. public static void WakeOnLan(string strMac)
    2. {
    3. // Byte[] MAC erstellen
    4. byte[] mac = new byte[6];
    5. for (int i = 0; i < 6; i++)
    6. mac[i] = Convert.ToByte(strMac.Substring((2 * i), 2), 16);
    7. // MagicPacket Bytes
    8. List<Byte> magicPacket = new List<Byte>();
    9. for (int i = 0; i < 6; i++)
    10. magicPacket.Add(byte.MaxValue);
    11. // 16 x MAC -Adresse zum MagicPacket hinzufügen
    12. for (int i = 0; i < 16; i++)
    13. magicPacket.AddRange(mac);
    14. // Sende WOL Paket.
    15. IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 9);
    16. using (UdpClient udp = new UdpClient())
    17. udp.Send(magicPacket.ToArray(), magicPacket.Count, endPoint);
    18. // Event feuern
    19. SendMagicPacket(endPoint.Address, endPoint.Port, mac, magicPacket.ToArray());
    20. }




    Danke für die Antworten.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Fakiz“ ()

    Wie ich's gesagt habe, die MAC-Adresse war falsch. In so einem Fall ist Debugging eine echt feine Sache. ;)
    Nochmal:

    Trade schrieb:

    Warum übergibst Du dann keine Instanz und holst die Bytes aus der raus? Dann sparst Du Dir das Encoding.ASCII.GetBytes-Zeug.

    Wenn Du das so machst, funktioniert das zu 100% und spart ziemlich viel redundanten Code, der nur rumkonvertiert.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Trade“ ()

    Hab ich nun Implementiert, ich habe mein Projekt um eine Serializer -Klasse und meine Einstellungs -Klasse um ein byte -Array erweitert. Nun kann ich bei Bedarf beim Server (mein PC) die MAC -Adresse anfragen und in den Globalen -Einstellungen speichern.