在區域網路中,可以傳送 Magic Packet 給主機的網路卡,Magic Packet 內容開頭有6個 "FF",再接 16 個網路卡 MAC,當主機版有開啟支援 Wake on LAN 功能,網路卡接收到符合條件的 Magic Packet,就能開啟電腦。(每個主機版關於 Wake on LAN 的名稱不盡相同,例如 PME Event Wake Up、Power On By PCI Devices...)
另一個影響能否網路開機的設定,在作業系統裡面裝置管理員,網卡裝置內容裡的電源管理,需勾選「允許這個裝置喚醒電腦」。
假設網路卡 MAC 為:01-02-03-04-05-06
Magic Packet 內容則為:
FFFFFFFFFFFF010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506010203040506
然後以 UDP 通訊協定傳送給電腦的 port 7、或 port 9
所以實現網路開機的方式,就是在區網內想辦法傳送給目標電腦網卡 Magic Packet,如果用來傳送 Magic Packet 的設備(Server),平常也有對外連線,也可達成在外網開機的效果。
以下 PHP 傳送 Magic Packet 範例來源
WOL: Wake-on-LAN Tutorial with Bonus PHP Script
僅稍微修改後如下:
class WakeOnLan { /** * 喚醒電腦 * @param type $addr ,目標IP 或 廣播位址(格式 01-02-03-04-05-06 或 01:02:03:04:05:06) * @param type $mac * @param type $port , 7 or 9 * @return boolean */ public function wake($addr, $mac, $port) { $mac = str_replace("-", ":", $mac); $addr_byte = explode(':', $mac); $hw_addr = ''; for ($a = 0; $a < 6; $a++) { $hw_addr .= chr(hexdec($addr_byte[$a])); } // 開頭六個 "FF" $msg = chr(255) . chr(255) . chr(255) . chr(255) . chr(255) . chr(255); // 16個MAC for ($a = 1; $a <= 16; $a++) { $msg .= $hw_addr; } // 開一個 UDP 的 socket // AF_INET:IP4 // SOCK_DGRAM:The UDP protocol is based on this socket type // SOL_UDP:使用 UDP 通訊協定 $skt = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); $err = array(); if ($skt === false) { $err[] = "Error creating socket!"; $err[] = "Error code is '" . socket_last_error($skt) . "' - " . socket_strerror(socket_last_error($skt)); throw new Exception(implode("\n", $err)); } else { // 設定使用broadcast廣播訊息 // $opt_ret = socket_set_option($skt, 1, 6, TRUE); $opt_ret = socket_set_option($skt, SOL_SOCKET, SO_BROADCAST, true); if ($opt_ret === false) { $err[] = "setsockopt() failed, error: " . socket_strerror(socket_last_error($skt)); throw new Exception(implode("\n", $err)); } if (socket_sendto($skt, $msg, strlen($msg), 0, $addr, $port)) { //Magic Packet sent successfully $res = trim(socket_strerror(socket_last_error($skt))); socket_close($skt); return $res; } else { $err[] = "Magic packet failed!"; throw new Exception(implode("\n", $err)); } } }}$WOL = new WakeOnLan();try { $res = $WOL->wake('192.168.0.255', "01-02-03-04-05-06", 7); $res = $WOL->wake('192.168.0.255', "01-02-03-04-05-06", 9); var_dump($res);} catch (Exception $ex) { var_dump($ex->getMessage());}
$a = get_defined_constants(TRUE);foreach ($a['sockets'] as $constant => $value) { printf("%-25s %d", $constant, $value);}
網路喚醒 - 維基百科,自由的百科全書
設定Windows 8網路喚醒(Wake On LAN) - 黑暗執行緒
PHP: socket_create - Manual
PHP: socket_set_option - Manual
PHP: socket_get_option - Manual
arduino - PHP : Send an UDP broadcast message , and wait the response - Stack Overflow
小信豬的原始部落: [TCP/IP Illustrated] Broadcasting & Multicasting