Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#
Article

Wake-On-Lan Class

Rate me:
Please Sign up or sign in to vote.
4.76/5 (19 votes)
27 Oct 20033 min read 145.3K   2.2K   80   23
Class to wake up a remote machine by sending a Wake-On-Lan packet.

Sample Image - wolclass.gif

Introduction

This class provides the functionality to wake up a machine over a local area network. There is not yet any functionality to use directed broadcasts, if your router supports it. The VS.NET project contains the class itself and a little command line app class which makes use of it.

Background

The basic Idea was to provide a web based interface to wake up other machines from an always running server. Why want that? Because I usually forget some actual working files on my desktop client at home or work, but I don't want them to be running all the time. And having a ASP.NET enabled always running web server at hand makes me wanting a pure .NET based solution, getting rid of the old Com-Objects or even worse command line tools. Here you will not find any ASP.NET code, but it should be no big deal for you to make use of the class in an ASP.NET environment, cause there are only two lines of code to add.
I named the class Magic Packet after AMD's registered trademark how developed this technology and provide some good background information.

Using the code

First you need to instantiate a MagicPacket object by presenting a MAC-Address to the class constructor. This Object represents now the ability to start this particular computer within the LAN. Next step is just to call the objects WakeUp() method. There is also a read only property called macAddress to read out the objects MAC address.

C#
if (macOK==true) 
{
    //create MagicPacket
    MagicPacket wakeUpPacket = NetTools.MagicPacket(macAdress);
    //Wake Up call
    byteSend = wakeUpPacket.WakeUp();
    Console.WriteLine("{0} Byte Send to {1}", byteSend, 
        wakeUpPacket.macAdress);
}

MagicPacket Class

The MagicPacket class itself is more or less self describing. I'm using System.Text.RegularExpressions just to make my life easy getting rid of all unwanted characters in the provided MAC-Address sting. Otherwise I would have to write a lot more code for string checking and I usually prefer to ignore things I don't like rather than handling those exceptions. What brings us to the class method Mac2Byte, this function has to convert the 12 digit string containing the MAC-Address in hexadecimal format (I think it is just common because nobody really wants to keep a 48 bit long sequence in mind :) to the byte array format.

C#
protected static byte[] Mac2Byte(string strMacAddress) 
{
    string macAddr; byte[] 
    macBytes = new byte[BYTELENGHT]; 
    //remove all non 0-9, A-F, a-f characters 
    macAddr = Regex.Replace(strMacAddress, @"[^0-9A-Fa-f]", ""); 
    //check if it is now a valid mac adress 
    length if (!(macAddr.Length == BYTELENGHT*2)) 
        throw new ArgumentException("Mac Adress must be " + 
             (BYTELENGHT*2).ToString() + 
              "digits of 0-9, A-F, a-f characters in length."); 
    string hex; 
    for (int i=0; i < macBytes.Length;i++)
    {
        hex = new String(new Char[] {macAddr[i*2], macAddr[i*2+1]});
        macBytes[(i)] = byte.Parse(hex, 
             System.Globalization.NumberStyles.HexNumber); 
    }
    return macBytes; 
} 

After converting the MAC-Address to byte format we can now create the payload. Especially here I decided to use class wide constants in the old C coder style to enhance readability and maintainability.

C#
protected static byte[] CreatePayload(byte[] macAddress) 
{
    byte[] payloadData = new byte[HEADER+MAGICPACKETLENGTH*BYTELENGHT];
    for (int i=0; i<HEADER; i++) 
    {
        payloadData[i] = byte.Parse("FF", 
             System.Globalization.NumberStyles.HexNumber);
    }
    for(int i=0; iMAGICPACKETLENGTH; i++)
    {
        for(int j=0;jBYTELENGHT;j++)
        {
            payloadData[((i*BYTELENGHT)+j)+HEADER] = macAddress[j];
        }
    }
    return payloadData;
}

The last thing to do is to get the packet on the network. This is almost as easy as it sounds. Just instantiate a Socket and send the payload in byte array format. As we are using UDP and don't require any answer we can just do it in a send and forget style.

C#
protected static int SendUDP(byte[] Payload, IPEndPoint EndPoint)
{        
    int byteSend;
    //create a new client socket...
    Socket socketClient = new Socket(EndPoint.AddressFamily, 
        SocketType.Dgram, ProtocolType.Udp);
    try
    {
        //open connection...
        socketClient.Connect(EndPoint);
        //send MagicPacket(TM)...
        byteSend = socketClient.Send (Payload, 0, Payload.Length, 
           SocketFlags.None);
    }
    catch (SocketException ex)
    {
        throw ex;
    }
    finally
    {
        socketClient.Close();
    }
    return byteSend;
}

Doing the coding

Using sockets with .NET is absolutely straight forward. So the most thoughts I had to put in as creating the MagicPacket payload with the Ethernet broadcast address "FF FF FF FF FF FF" followed by 16 times of the targets MAC-Address. And the conversion of the MAC-Address from standard hex format to byte format taken by the socket. But the trouble converting the MAC-Address was quite a breeze thanks to neilck and his hex encoding/decoding class, providing me a good example.

Issues

Having this very basic class running now the next step I'm thinking of is to add at least the ability to use directed broadcasts and to solve dns names for a remote target network. You might also think about some RARP functionality to solve IP-Address into MAC-Address, but there for you need to maintain a table for a long time and it might not be the best solution because the machine you are going to wake is not running in the moment, so I already discarded that idea. Also I was thinking about how to check if the machine has started, but I haven't figured out how to do it the smart way.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Team Leader
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhat is the license of this code? Pin
angelo moscati16-Oct-11 4:49
angelo moscati16-Oct-11 4:49 
AnswerRe: What is the license of this code? Pin
mkruppa16-Oct-11 10:47
mkruppa16-Oct-11 10:47 
QuestionEasy to extend to use across networks Pin
Per Hejndorf2-Aug-11 23:08
Per Hejndorf2-Aug-11 23:08 
Questioncan be improved using .Net's built-in PhysicalAddress Pin
Member 40957453-Sep-09 1:50
Member 40957453-Sep-09 1:50 
Generalhi Pin
rojasrojas13-Sep-08 13:48
rojasrojas13-Sep-08 13:48 
GeneralBroadcast was Re: hi Pin
mkruppa13-Sep-08 23:55
mkruppa13-Sep-08 23:55 
GeneralRe: Broadcast was Re: hi Pin
rojasrojas14-Sep-08 6:11
rojasrojas14-Sep-08 6:11 
GeneralRe: Broadcast was Re: hi Pin
mkruppa14-Sep-08 9:57
mkruppa14-Sep-08 9:57 
This beahvior is absolutly correct, as broadcasts will not be routed outside a subnet.
GeneralRe: Broadcast was Re: hi Pin
rojasrojas14-Sep-08 10:24
rojasrojas14-Sep-08 10:24 
GeneralRe: Broadcast was Re: hi Pin
mkruppa15-Sep-08 3:19
mkruppa15-Sep-08 3:19 
GeneralRe: Broadcast was Re: hi Pin
rojasrojas16-Sep-08 20:57
rojasrojas16-Sep-08 20:57 
GeneralRe: Broadcast was Re: hi Pin
mkruppa16-Sep-08 23:43
mkruppa16-Sep-08 23:43 
GeneralRe: Broadcast was Re: hi Pin
rojasrojas16-Sep-08 23:50
rojasrojas16-Sep-08 23:50 
GeneralRe: Broadcast was Re: hi Pin
mkruppa17-Sep-08 1:44
mkruppa17-Sep-08 1:44 
GeneralRe: Broadcast was Re: hi Pin
rojasrojas17-Sep-08 3:11
rojasrojas17-Sep-08 3:11 
GeneralRe: Broadcast was Re: hi Pin
mkruppa17-Sep-08 5:59
mkruppa17-Sep-08 5:59 
GeneralRe: Broadcast was Re: hi Pin
rojasrojas25-Sep-08 2:20
rojasrojas25-Sep-08 2:20 
GeneralWonderful work Pin
Member 21686773-Aug-05 14:07
Member 21686773-Aug-05 14:07 
Generalwol Pin
ramazoti7-Nov-03 10:51
ramazoti7-Nov-03 10:51 
GeneralRe: wol Pin
mkruppa7-Nov-03 21:51
mkruppa7-Nov-03 21:51 
GeneralRe: wol Pin
ramazoti19-Nov-03 5:52
ramazoti19-Nov-03 5:52 
GeneralRe: wol Pin
the-unforgiven19-Jul-05 10:01
the-unforgiven19-Jul-05 10:01 
GeneralRe: wol Pin
tsurutsuru22-Sep-04 6:11
tsurutsuru22-Sep-04 6:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.