WakeUp on LAN [Encender una PC remotamente] Fecha: 10/Abr/2005
(05/04/2005)
|
¿¿¿Como funciona???
El WakeUp On Lan, permite encender una pc de forma remota, siempre y cuando la computadora remota lo permita y este habilitado desde el BIOS de la pc. Para permitir el encendido remoto, la pc que se va a encender requiere estar conectada via ethernet (configuracion utilizada en casi todas las redes) y poseer la tecnología ACPI, que aunque es una tecnología bastante antigua, solo es permitido en las computadoras con fuentes ATX, las cuales vienen en todos los modelos desde hace unos cuantos años.
Para permitir el encendido, la computadora debe estar "escuchando" (o listening) en el puerto 9 de la interfaz de red, esto se hace solamente habilitando una opción en el BIOS (siempre y cuando este permitido!). Los mensajes que espera recibir son de cualquier protocolo, aunque se usa UDP por el modelo de coneccion que utiliza.
El protocolo
A la hora de enviar un mensaje, hay que utilizar un protocolo muy sencillo para identificar la pc. La identificación utilizada se basa en la dirección ethernet (Ethernet Address), para ver la dirección ethernet de una pc se puede proceder de muchas formas, aunque las 3 mas comunes que funcionan en Windows/DOS son:
- En la misma maquina: Ir a Inicio->Ejecutar, y escribir CMD, presionar enter. Una vez abierto el cmd, escribir "IPCONFIG /ALL" (sin las comillas) y presionar enter. Aparecera una lista con las configuraciones de las placas de red instaladas en la PC actual, uno de los items dice Physical Address, alli podra ver la direccion ethernet. Ejemplo: 00-50-BA-87-2C-11
- En la misma maquina: Ir a "Mis Sitios de Red" y hacer click en donde dice "Ver Conecciones de Red" en la parte izquierda de la pantalla. Una vez hecho esto, se debe hacer doble click sobre una coneccion, e ir al tab (pestaña) que dice soporte; hacer click en el boton Detalles, y ahi esta!. Ejemplo: 00-50-BA-87-2C-11
- Desde una maquina remota: (Recuerde que las 2 pcs deben estar en la misma red). Ir a Inicio->Ejecutar, y escribir CMD, presionar enter. Una vez abierto el cmd, escribir "PING xxx.xxx.xxx.xxx" (sin las comillas) en donde xxx.xxx.xxx.xxx es el ip de la otra maquina. Luego tipear "ARP -A" (sin las comillas), esto mostrara una lista de los ips en relacion con las direcciones ethernet. En caso de haber muchos ips, se puede escribir "ARP -D *" (sin las comillas) para borrar la lista y que sea mas facil encontrarlo. Ejemplo: 00-50-BA-87-2C-11
El protocolo esta compuesto por un encabezado igual a 6 caracteres 0xFF (255 en decimal considerando el 0), por lo que quedaria algo como: FFFFFFFFFFFF; despues este encabezado es seguido por la direccion de ethernet 16 veces. es decir si la direccion ethernet es 00-50-BA-87-2C-11, el mensaje completo quedaria asi (sin los espacios y sin los guiones):
FF FF FF FF FF FF - 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11- 00 50 BA 87 2C 11
Haciendo la aplicacion en .NET
Para crear el mensaje, lo unico que hay que hacer es crearlo en un array de bytes, es decir un byte[], el largo del mensaje es siempre 102, ya que son 6 bytes del encabezado más 6 bytes de la direccion ethernet multiplicado por 16 veces, es decir 6+6*16=102.
Despues hay que abrir el socket para enviar los datos, lo cual se hace utilizando la clase System.Net.Sockets.Socket, despues se crea un objeto IPEndPoint, el cual especifica a donde va a ser enviado el mensaje, por default yo utilizo la opcion IPAddress.Broadcast para que el mensaje sea enviado a toda la red, pero esto se puede reemplazar por IPAddress.Parse("192.168.0.31"), para que el mensaje sea enviado a un solo ip, en donde 192.168.0.31 es el ip de la maquina a encender, en el constructor del objeto IPEndPoint, tambien hay que especificar un puerto, hay que utilizar el 9 ya que el WakeUp On Lan utiliza este puerto y no es configurable (al menos en la mayoria de los casos).
Por ultimo se utiliza el metodo SendTo para enviar el mensaje, este metodo requiere como argumentos un IPEndPoint y el mensaje a enviar.
Este es el codigo funcionando, o al menos para mi :), si se lo copia en el Main de una aplicacion o en cualquier otro lugar deberia funcionar.
byte[] UdpMessage = new byte[102];// Escribo el Header (encabezado) del mensajeUdpMessage[0] = 0xFF;UdpMessage[1] = 0xFF;UdpMessage[2] = 0xFF;UdpMessage[3] = 0xFF;UdpMessage[4] = 0xFF;UdpMessage[5] = 0xFF;for (int Count = 0 ; Count < 16 ; Count++){// Escribo la direccion ethernet 16 veces...int Start = Count*6+6;UdpMessage[Start+0] = 0x00;UdpMessage[Start+1] = 0x0A;UdpMessage[Start+2] = 0xE6;UdpMessage[Start+3] = 0x71;UdpMessage[Start+4] = 0xCF;UdpMessage[Start+5] = 0x05;}Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 9);sock.SendTo(UdpMessage, iep);sock.Close();Espacios de nombres usados en el código de este artículo:
System.Net
System.Net.Sockets
Aplicacion de ejemplo: Diegos_WakeUpOnLan.zip - 16 KB