使用 Magic Packet 完成 WOL 唤醒,其实就是使用 UDP 发送一个数据到目标计算的指定端口,那么其实不需要使用各种程序或者 app,使用 php 也可以完成操作。
将以下代码保存为 wol.class.php 文件
* 实现网络唤醒功能
*/
class WOL
{
private $hostname; // 唤醒设备的 url 地址
private $mac; // 唤醒设备的 mac 地址
private $port; // 唤醒设备的端口
private $ip; // 唤醒设备的 ip 地址(不是必须的,程序会自动根据 $hostname 来获取对应的 ip )
private $msg = array(
0 => "目标机器已经是唤醒的.",
1 => "socket_create 方法执行失败",
2 => "socket_set_option 方法执行失败",
3 => "magic packet 发送成功!",
4 => "magic packet 发送成功!"
);
function __construct($hostname,$mac,$port,$ip = false)
{
$this->hostname = $hostname;
$this->mac = $mac;
$this->port = $port;
if (!$ip)
{
$this->ip = $this->get_ip_from_hostname();
}
}
public function wake_on_wan()
{
if ($this->is_awake())
{
return $this->msg[0]; // 如果设备已经是唤醒的就不做其它操作了
}
else
{
$addr_byte = explode(':', $this->mac);
$hw_addr = '';
for ($a=0; $a<6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a]));
$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
for ($a=1; $a<=16; $a++) $msg .= $hw_addr;
// 通过 UDP 发送数据包
$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($s == false)
{
return $this->msg[1]; // socket_create 执行失败
}
$set_opt = @socket_set_option($s, 1, 6, TRUE);
if ($set_opt < 0)
{
return $this->msg[2]; // socket_set_option 执行失败
}
$sendto = @socket_sendto($s, $msg, strlen($msg), 0, $this->ip, $this->port);
if ($sendto)
{
socket_close($s);
return $this->msg[3]; // magic packet 发送成功!
}
return $this->msg[4]; // magic packet 发送失败!
}
}
private function is_awake()
{
$awake = @fsockopen($this->ip, 80, $errno, $errstr, 2);
if ($awake)
{
fclose($awake);
}
return $awake;
}
private function get_ip_from_hostname()
{
return gethostbyname($this->hostname);
}
}
?>
幻数据包(Magic Packet)
由 AMD 公司提出,幻数据包是一个广播帧,包含待唤醒计算机的 MAC 地址。完成的幻数据包最简单的构成是 6 字节的 255(FF FF FF FF FF FF FF),紧接着为 48 位 MAC 地址,重复 16 次,数据包共计 102 字节。通常数据包含在 UDP 协议中。
再创建一个 wol.php 文件进行调用
<?php
include("wol.class.php");
$WOL = new WOL("你的 IP 或动态域名","目标计算机网卡 mac 码","唤醒端口");
$status = $WOL->wake_on_wan();
echo $status;
?>
访问 wol.php 文件即可唤醒计算机。