Has it ever happened to you that you are sitting with your laptop and need to do something with a computer on your local network and it turns out that computer is in a sleep mode and you have to walk to it and move the mouse or press some key to wake it up and then come back to your laptop to do what you initially wanted to do with it? Indeed, if you have to walk to a computer rather than remotely access it than the benefit of having local network is already somewhat undermined. My particular situation is worsened by the fact that I usually work on my laptop in the living room on the first floor and from time to time I need an access (ideally remote access) to my desktop on the second floor on the opposite side of our house so it is not all that convenient, especially if I just want to do something really small and get it done quickly. For example, if I am ready to do some programming and realize that I forgot to check in some code while I was working on my desktop. And then the desktop is already in a sleep mode (I do care about power consumption) so the remote desktop connection is not an option. Or even worse if for whatever reason I need to access my desktop for just a minute from my work computer at the office. I believe you can think of some other examples too.
All this lead me to research tools which would allow me to wake up a computer remotely. Google immediately brought me this article in Wikipedia: Wake-on-LAN. Seems like this is exactly what I need. There are several limitations mentioned in the article but none of them is a blocker for my computers’ setup. Looking at the article it might seem that it is somewhat complex to implement in code, but turned out that there is only one small paragraph that really matters for implementing this solution in code: Magic Packet. Without further lyrics let’s dive into the code that allows us to wake up a computer on local network. Notice that the snippet is really small and simple and mostly consists of comments (the majority of which are copy/paste from the Magic Packet paragraph in the Wikipedia article).
// see http://en.wikipedia.org/wiki/Wake-on-LAN#Magic_Packet
// The magic packet is a broadcast frame containing anywhere within its payload 6 bytes of 255—
// all bits set to the on position—which has
// the hexadecimal representation of: FF FF FF FF FF FF
let header = [for x in 1..6 -> 0xFFuy]
// , followed by sixteen repetitions of the target computer's 48-bit MAC address.
let tail (mac: byte list) = [for x in 1..16 do yield! mac]
// the MAC address of the computer we are trying to wake up
let mac = [0x00uy; 0x22uy; 0x1Duy; 0xCBuy; 0xE9uy; 0xA9uy]
// and now form the magic packet
let magicPacket = header @ (tail mac)
// it is about time to send our magic packet to the sleeping PC
let udp = new UdpClient()
// the magic packet may be sent as a broadcast packet of any network-
// and transport-layer protocol.
// It is typically sent as a UDP datagram to port 0, 7 or 9
udp.Connect(IPAddress.Broadcast, 0(* could be 7 or 9 *))
udp.Send(List.toArray magicPacket, magicPacket.Length) |> ignore
Yes, it is really that simple. Of course this is just a snippet and I have hardcoded MAC address and so on but I can really just save this code as fsi script and run whenever I need or run it in Visual Studio or F# interactive. I will probably end up making it a WCF service and host it on my home server so that I can wake up my computers from any place that has an internet connection. And ASP.NET MVC client plus an app for my smartphone. As Windows Phone 7 recently came under my learning radar I may even end up with WP7 client for the server Stay tuned!