返回

Wol:广域网远程网络唤醒

简单写了一下

缘起

最近在看一些前端编程的入门文档。

动手做了一个小项目,用到了PHP、jQuery、JavaScript、bootstrap等。

实际上核心的代码还是从StackOverflow查找到的。

说明

用于在广域网环境下的远程唤醒。

需要提供IP(提供域名会自动转化为IP),端口(默认为7),以及MAC地址。

前端使用jQuery,界面构建用了bootstrap。

后端使用PHP。两个文件相互分离。从URL中读取信息,便于收藏和重复使用。

项目地址(DEMO)

部署在ProFreeHost的免费服务器上。

远程网络唤醒 (unaux.com)

不知道为什么跑不了。虽然可以运行,但是数据不会发送到主机。

在replit的托管服务上也跑不了。害得我重试了好久。ping倒是可以ping,是不是socket_send函数不能使用?但是又没有报错。很奇怪。

在自己的服务器上就能够跑:

wol.kermsite.com

源代码:

kerms0/WOL-php (github.com)

image-20211209203615040
image-20211209203615040

实现原理

大概就是从index.html收集信息,然后生成一个url指向task.php。使用这个脚本来执行任务。

核心代码是从网上找的。但是后来也多少研究了一下。

    function wol($broadcast, $mac, $port){
    # 这个是对传入的mac地址作预处理
    $mac_array = preg_split('#:#', $mac); //print_r($mac_array);
    $hwaddr = '';
        # 生成魔包数据。这个包从一堆255开始,然后接六次mac地址。
        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
        # 兴建一个socket。这些参数可以在手册上查到,大意就是:使用ipv4协议,使用不可靠的套接字,使用UDP协议。
        $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
        if ($sock){
        # 这里大概是检查这个设置有没有问题。
        $options = socket_set_option($sock, 1, 6, true);
            # 如果没有问题就发送数据。第一个是sock参数,第二三个是数据,最后两个是目标地址
            if ($options >=0){    
            $e = socket_sendto($sock, $packet, strlen($packet), 0, $broadcast, $port);
            socket_close($sock);
            }    
        }
    }  //end function 

DEBUG-问题分析

我一共尝试在3个免费的虚拟空间上部署这个服务。

所有空间都无法执行完成wol函数,也就是只有第一行提示,没有第二行提示。

image-20211209205138803
image-20211209205138803

服务地址:

http://kermspublic.unaux.com/

http://kermsite.byethost3.com/

最后我甚至使用了Github上另外一个现成的源码进行测试。但是返回了一个这样的错误:

image-20211209210314590
image-20211209210314590

怀疑是这些空间都限制了某些权限。而正常使用wol都必须带有这些权限。导致完全用不了。

另外,我在Replit云端空间,虽然可以正常执行wol函数,但是实际上服务器没有收到数据。使得我一度认为程序有问题。使用ping脚本倒是可以。

也就是说Replit可以运行TLS,但是不能运行UDP

非常奇怪。除此之外,使用Replit对9端口进行ping也会收不到回应。难道是这个端口有问题嘛?但是我也已经关闭防火墙,并且在服务商处开放端口了。

实际上这个程序在我的服务器上是可以正常运行,并且显示的:

image-20211209205223037
image-20211209205223037

所以这一次我弄了很久。甚至还专门学习了各种知识。唉。

附录

参考文献

  1. php - Wake on lan script that works - Stack Overflow
  2. wake-on-lan.php/wake-on-lan.php at master · AndiSHFR/wake-on-lan.php (github.com)
  3. wake-on-lan.php/wake-on-lan.php at master · AndiSHFR/wake-on-lan.php (github.com)
  4. wake-pc/index.php at master · szabodanika/wake-pc (github.com)
  5. PHP: socket_sendto - Manual
  6. PHP - 网络唤醒(WOL)功能的实现 (hangge.com) 这个也给出了一个中文的代码版本。但是很奇怪的是必须使用域名进行唤醒?
  7. PHP: gethostbyname - Manual

版权信息

本文原载于kermsite.com,复制请保留原文出处。

Built with Hugo
Theme Stack designed by Jimmy