是否有使用Web语言的局域网唤醒脚本,最好是有效的PHP?还有一个包含一些有关如何使其工作的文档,例如需要在服务器上启用的内容等
function wol($broadcast, $mac)
{
$hwaddr = pack('H*', preg_replace('/[^0-9a-fA-F]/', '', $mac));
// Create Magic Packet
$packet = sprintf(
'%s%s',
str_repeat(chr(255), 6),
str_repeat($hwaddr, 16)
);
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($sock !== false) {
$options = socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, true);
if ($options !== false) {
socket_sendto($sock, $packet, strlen($packet), 0, $broadcast, 7);
socket_close($sock);
}
}
}
应该可以工作 - 使用广播 IP 地址和 MAC 地址调用它
这是一个古老的问题,但它仍然是谷歌的第一个结果,所以这是我经过一些研究后最终所做的:
先决条件:
- 同一网络上的 Linux 盒子
- 从系统的软件包管理器
wakeonlan
(即sudo apt-get install wakeonlan
)
现在脚本就像这样简单:
<?php
# replace with your target MAC address
$mac = 'aa:bb:cc:11:22:33';
exec("wakeonlan $mac");
?>
希望对某人有所帮助。
HTML (test.htm)
<body>
<a href="test.php?mymac=XX:XX:XX:XX:XX:XX">Click to WOL XX:XX:XX:XX:XX:XX</a>
</body>
PHP(测试.php)
<?php
$mymac = $_REQUEST['mymac'];
wol("255.255.255.255", $mymac);
echo 'WOL sent to '.$mymac;
function wol($broadcast, $mac){
$mac_array = preg_split('#:#', $mac); //print_r($mac_array);
$hwaddr = '';
foreach($mac_array AS $octet){
$hwaddr .= chr(hexdec($octet));
}
//Magic Packet
$packet = '';
for ($i = 1; $i <= 6; $i++){
$packet .= chr(255);
}
for ($i = 1; $i <= 16; $i++){
$packet .= $hwaddr;
}
//set up socket
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($sock){
$options = socket_set_option($sock, 1, 6, true);
if ($options >=0){
$e = socket_sendto($sock, $packet, strlen($packet), 0, $broadcast, 7);
socket_close($sock);
}
}
} //end function wol
?>
由于 split()
函数已从 PHP 7.0.0 中删除,因此此脚本使用 preg_split()
与当前和以前的 PHP 版本兼容。
将 HTML 中的XX:XX:XX:XX:XX:XX
替换为目标 MAC 以测试脚本。
建立在前面的答案之上。必须将udp端口设置为9并在MAC对我起作用之前再重复几次:
function wol($mac)
{
$hwaddr = pack('H*', preg_replace('/[^0-9a-fA-F]/', '', $mac));
// Create Magic Packet
$packet = sprintf(
'%s%s',
str_repeat(chr(255), 6),
str_repeat($hwaddr, 20)
);
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($sock !== false) {
$options = socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, true);
if ($options !== false) {
socket_sendto($sock, $packet, strlen($packet), 0, "255.255.255.255", 9);
socket_close($sock);
}
}
}
请阅读您是否在 Docker 中运行 PHP,否则忽略这一点。
似乎来自 docker 的 UDP 广播没有正确路由(可能只在容器本身中广播,而不是在主机上广播)。
您可以尝试设置(CLI)--network host
或(撰写)network_mode: host
,但对于PHP来说,这会导致问题。
您无法直接发送UDP WoL消息,因为您尝试控制的设备处于"离线"状态,它不会显示在路由器的ARP表中,因此无法传递直接消息。
我最终运行了@reboot root /usr/bin/php -S 0.0.0.0:8877 -t /home/user/php
并将 wol.php 文件放在那里。
作为一个"更合适"的解决方案,你可以运行一个"wol proxy"docker 容器来做到这一点(但在network host
特权的 docker 容器中)。