使用PHP远程唤醒计算机(远程开机)

原理

Wake-On-LAN简称WOL,是一种电源管理功能;它是由IBM公司提出的网络唤醒标准,目前该标准已被大多数主板厂商支持。支持该标准的主板允许从远程通过网络唤醒计算机,也就是远程开机。

如何实现

简单来说只需要两步:
1.需要远程唤醒的计算机设置好允许远程WOL唤醒
2.通过软件向远端计算机发送唤醒请求

BIOS 设置

计算机重启进入BIOS,进入主板BIOS后寻找以下选项:
1.Power On by PCIE/PCI devices
2.Power On by Onboard Lan
3.Wake up on LAN
4.Resume on LAN
5.Power on PME
不同品牌的主板,名字不同,基本上就是上面这几个名字,找到并设置为 Enabled

设置允许唤醒

找到当前正在使用的网卡,设置允许唤醒。

查看物理地址(MAC)

查看当前网卡的物理地址,后面唤醒时需要用到。

使用唤醒软件

安卓APP:Wake On Lan (google play上有),也可以点击这里下载
PC 客户端:下载链接

在安卓APP上添加要唤醒的设备

注:确保你的手机和要唤醒的计算机在同一个网络。

测试唤醒

在 PC 客户端,点击封包监控诊断,同时,在移动端运行 “wake on lan”,点击你的 pc 设备。你就会看到在 pc 端的窗口会显示数据包信息。

现在可以关闭你的计算机测试唤醒效果了。

使用PHP唤醒计算机

直接上代码:

$ip='XXX.XXX.XXX.XXX';
$mac='XX-XX-XX-XX-XX-XX';
$WOL = new WOL($ip, $mac);
$status = $WOL->wake_on_wan();
echo $status;
exit();

class WOL
{
    private $ip;          // The IP address of the wake-up device
    private $mac;         // The mac address of the wake-up device
    private $port;        // The port of the wake-up device

    private $msg = array(
        0 => "The target machine is already awake.",
        1 => "socket_create execution failed",
        2 => "socket_set_option execution failed",
        3 => "magic packet Sent successfully!",
        4 => "magic packet Failed to send!"
    );

    function __construct($ip, $mac, $port = "9")
    {
        $this->ip = $ip;
        $this->mac = $mac;
        $this->port = $port;
    }

    public function wake_on_wan()
    {
        if ($this->is_awake()) {
            return $this->msg[0]; // If the device is already awake, no other operations will be performed
        } 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;
            // Send data packets via UDP
            $s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

            if ($s == false) {
                return $this->msg[1]; // socket_create Execution failed
            }

            $set_opt = @socket_set_option($s, 1, 6, TRUE);

            if ($set_opt < 0) {
                return $this->msg[2]; // socket_set_option Execution failed
            }

            $sendto = @socket_sendto($s, $msg, strlen($msg), 0, $this->ip, $this->port);
            $sendto = @socket_sendto($s, $msg, strlen($msg), 0, $this->mac, $this->port);

            if ($sendto) {
                socket_close($s);
                return $this->msg[3]; // magic packet Sent successfully!
            }

            return $this->msg[4]; // magic packet Failed to send!

        }
    }

    private function is_awake()
    {
        $awake = @fsockopen($this->ip, 80, $errno, $errstr, 2);

        if ($awake) {
            fclose($awake);
        }

        return $awake;
    }
}

程序调试

如果关机后,使用以上PHP程序并没有唤醒计算机,可以在需唤醒的计算机上打开前面安装的客户端程序,监听是否收到了数据包以及收到的数据包的ip地址及MAC地址是否正确:

一个带界面的PHP唤醒程序

点击下载

常见问题

1.不同网段无法开机
实际测试发现,发起唤醒的设备与需唤醒的设备必须在同一个子网才可以,例如都在192.168.1.X这样的局域网中,如果其中一个在192.168.1.x,另一个在192.168.2.x,那么就无法唤醒。
2.关机一段时间后无法开机
有的会出现电脑关机一段时间后,无法唤醒的情况,网上搜索了说是要设置arp静态绑定,将IP地址与MAC地址进行绑定,但我这边没有路由器管理权限,无法测试。

其他解决方案

后来购买了智能插座,直接手机上APP就可以操作让插座通电和关电,然后在电脑主板中设置通电就开机,这样也达到了远程开机的目的。
主板设置步骤可以查看:http://www.lotpc.com/dnzs/9385.html

参考:https://zhuanlan.zhihu.com/p/107387999

发表评论

邮箱地址不会被公开。 必填项已用*标注