Remote Wakeup (or Wake On LAN (WOL))
£¨This is a fake, false, fault or whatever,
it simply doesn't work!)
A. First Edition
This is probably the most simple program I have posted in my personal website because it has a simple naive
function, namely to wake up a remote computer, by using the so-called wake on LAN or WOL.
Suppose that your supervisor gives you some computers which are all running in different floors of building and you happen to be doing a parallel computation job with those clusters, then will you be happy to take elevator to jump from floor to floor to see what the screen displays in each computer?
I think most of us won't like to do that. Windows XP supplies with a nice, easy "remote-desktop" which is like the ancient "PC Anywhere". Then one problem arises here. Can you remotely start the power and turn it off?
Turning off is not a big deal. One simple solution is to run dos command "shutdown" or write a small program to do it( Assuming you are as funny-about as I am with absolutely nothing to do.)
How about turning on? It is not so straight-forward and I am pretty sure it is not part of windows management because I cannot find any clue in windows help or MSDN etc.
It is up to you to implement with a very small step plus several hardware support.
¡¡
Here let me write down the configuration.
1. To turn on "remote-desktop", you need to go to "control-panel\system\remote" and check "allow users to connect remotely to this computer".
2. Make sure your user account is already granted with access by "select remote users" at same page. One simple trick in windows is that create same user with same password in all clusters.
3. Then you can use "remote-desktop" from "accessory\communication\remote-desktop".
Here is the hardware support for "remote-wakeup" or "wake on LAN" and some of them are simply what I read from various sources in internet.
1. Your OS must support this. window XP is OK.
2. Your network adaptor must support it. To enable it, go to "\local-network-connection\status\property" and click "configure" and choose "power management" to check "allow this device to bring this computer to be out of standby". Go to page "advanced" and choose "wakeup compatibilities" to make sure "magic frame" or "magic packet" is included.
3. Your motherboard or BIOS must support it. Reboot your computer and enter setup of BIOS to enable "remote wakeup" or "boot on LAN" or something similar (not quite sure).
4. Then the rest of it is just a little programming. The simple idea is to use UDP to send a special packet or "magic packet" to sleeping computer which only allow network adaptor monitoring incoming message. When NIC receives, it wakeup the OS. So, the understatement is that your hardware must support "ATX" or advanced power management.
5. What is the port number to send? It is by default 40000.
6. What is composed of the packet? It consists of a header and 16 times repeating of the mac address of sleeping machine. The header is 6 bytes of 0xFF. And each mac address is also 6 bytes. Therefore total 6+16x6 bytes.
7. How can I get mac address? And IP address of the machine?
I haven't found the way to convert IP to mac. And to acquire local mac address is simple. You can run "getmac" at command line. So, I simply hardcode everything.
E.Further improvement
¡¡
F.File listing
1. wakeup.cpp
¡¡
file name: wake.cpp
#include <winsock.h> #include <iostream> using namespace std; typedef unsigned char uchar; const int MagicPacketLength=6+6*16; const uchar MagicPacketHeader[6]= { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; /* the address of nicktcl const uchar macAddress[6]= { 0x00, 0x0F, 0xEA, 0xD0, 0xDF, 0x46 }; */ const uchar macAddress[6]= { 0x00, 0x13, 0xD3, 0x99, 0x19, 0xBA }; char packet[MagicPacketLength]; WSADATA wsadata; const int PortNumber=40000; int errCode; SOCKET mySocket; char buffer[32]; hostent* hostInfo; sockaddr_in address; void init() { if ((errCode=WSAStartup(0x2020, &wsadata))!=0) { switch (errCode) { case WSASYSNOTREADY: printf("WSASYSNOTREADY\n"); break; case WSAVERNOTSUPPORTED: printf("WSAVERNOTSUPPORTED\n"); break; case WSAEINPROGRESS: printf("WSAEINPROGRESS\n"); break; case WSAEPROCLIM: printf("WSAEPROCLIM\n"); break; case WSAEFAULT: printf("WSAEFAULT\n"); break; } exit(1); } if ((mySocket = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET) { errCode=WSAGetLastError(); exit(2); } } void assemblyPacket() { memcpy(packet, MagicPacketHeader, 6); for (int i=1; i<=16; i++) { memcpy(packet+6*i, macAddress, 6); } } void uninit() { WSACleanup(); } void wakeupComputer(char* name) { if ((hostInfo= gethostbyname(name))==NULL) { errCode=WSAGetLastError(); printf("gethostbyname error\n"); exit(4); } memset(&address, 0, sizeof(address)); //address.sin_addr=AF_INET; address.sin_family=hostInfo->h_addrtype; address.sin_port=PortNumber; memcpy(&address.sin_addr, hostInfo->h_addr, hostInfo->h_length); if ((errCode=connect(mySocket,(LPSOCKADDR) &address, sizeof(address)))!=0) { printf("error of connect\n"); exit(3); } assemblyPacket(); if ((send(mySocket, packet, MagicPacketLength, 0))==SOCKET_ERROR) { errCode=WSAGetLastError(); printf("send error\n"); exit(6); } } int main() { init(); printf("%s\n", "please enter your remote server name :"); //cin>>buffer; strcpy(buffer, "NICKATI"); wakeupComputer(buffer); uninit(); return 0; }
¡¡