电脑远程唤醒开机的办法

2023-3-8 12:31:19 [大杂烩 - PC与手机]

  工作中经常会有需要远程连接家里或办公室里的电脑,以查找资料,临时处理有关事务。过去往往就是电脑长期开着不关机。如果电脑长期开着但其实空闲的时候很长,不仅费电,而且也影响使用寿命。现在电脑都是连网的,长期开着还有数据安全问题。

  网上找了这么多远程唤醒开机的办法,经过测试,整理如下:

  一、最简单的办法:使用智能插座

  最近网上卖智能插座的很多了,比过去通过网络唤醒电脑要方便很多,也没有网关等限制。远程开机首推智能插座。我也是家里折腾网络很长时间,后来还是花几十块钱买一个智能插座搞定的。

  1、网上买一个智能插座(一般50元左右),家里得有可以连接的WIFI

  2、电脑机箱电源线通过智能插座连接到市电。

  3、按智能插座的使用说明,用手机配置WIFI、连接上智能插座。

  4、在电脑启动的BIOS设置(电脑启动时按DEL或F2键),-“高级模式” - “高级”选项卡,找到“高级电源管理(APM)”选项。然后再找 “断电恢复后电源状态”,其右边的选项中选择“电源开启”(不要选“最近状态”,这样如果在电脑上正常关机,就无法启动电脑)。按F10键保存,按Esc键退出重启。

  5、在手机上打开智能插座APP,将APP中的电源开关先关闭,再打开,这时候电脑就启动了。


  二、经典办法:网络远程唤醒
  这个办法有这么多前提条件:操作者能通过网络访问要启动的电脑。这就意味着:

   (1)通过内网启动:两者都在一个局域网,且相互能够通过网络访问。 

   (2)通过外网启动:要求知道要启动的电脑所在网络的外网IP,直接或者通过路由器(或其他电脑)能够通过TCP或UDP连接到这台电脑。路由器(或其他电脑)要支持IP/MAC绑定,或者支持”子网定向广播“,或者具备静态路由表。

  (一)局域网方案

  以办公室电脑远程启动为例。网络环境:局域网有出口公网IP,电脑在子网,且连接到房间的WIFI路由器,局域网中有一台服务器提供WEB服务且可被外网访问。这个实际是局域网解决方案,利用了WEB服务来穿透局域网。

  1、电脑设置:此电脑-管理-设备管理器-找到相应的网卡-属性:

  (1)电源管理选项卡:勾选“允许计算机关闭此设备以节约电源”和“允许此设备唤醒计算机”
  (2)高级选项卡:找到“唤醒幻数据包”(也叫“网络唤醒”、“魔术封包唤醒”、或者英文wake-on-magic-packet),将其改为“开启”状态。我在实际配置中,有台电脑中文属性都改了,仍然不行,后来发现还有一个英文的,改了开启后就成功了。

   2、在电脑启动时按DEL或F2键,进入BIOS设置,找到高级电源管理,将“PCIE设备唤醒”设置为“允许(Enabled)”

   3、 在电脑连接的房间WIFI路由器,进入管理配置的WEB页面,设置IP绑定,将电脑的IP地址和网卡的mac地址绑定,设置DMZ为电脑的IP,或者设置端口映射(IP为刚才绑定的IP,端口为8081等任意的)

   4、在局域网服务器WEB服务 中,加了一PHP代码,代码中配置好为房间路由器的IP地址、端口8081,唤醒幻数据包的结构是由6组FF前缀+16次重复MAC地址组成,这个MAC即要启动的MAC地址。

   5、要启动电脑时,通过手机等打开PHP网页,远行启动代码,电脑在关机状态会启动。

(二)家庭光纤上网的电脑启动方案

  这个方案的关键是需要一个外网IP。因为当前光纤上网电信局提供给光猫的大多数地方其实是内网地址,因此,要联系电信宽带管理人员,要一个公网IP。一般光猫没有子网定向广播功能,也不支持静态路由表或者IP绑定,因此需要在电脑和光猫间WIFI路由器。这样,在光猫上加上端口映射到WIFI路由器,WIFI路由器加IP绑定和端口映射到电脑。配置方法同前面所述。注意公网端口会有许多限制(如21、80等是不能用的),一般建议用大于1024的端口如18000等。


   (三)局域网内通过一台电脑批量启动一批电脑,有许多软件,可下载安装。


   我家里办公室多台电脑,采取上面的办法,还做了一个WEB管理页面,来统一管理电脑的远程启动、关机等。

    下载Aquila Technology的软件可以实现在电脑上远程唤醒其他的电脑,还可以捕捉唤醒数据包,来测试网络连接是否正常。如果仅是捕捉包,也可以用WireShark来捕包,过滤条件可以设置为 wol。

   测试中要注意一点:通过IP与MAC绑定方式,发送唤醒数据包的协议要用UDP。我在使用TCP测试时,如果你的电脑上对测试的端口(比如1080)并没有侦听服务,这时socket是无法打开连接的,因此数据包也无法发送出去。自然监测不到这个包。而使用UDP协议,不需要建立连接,就可以直接发送,这样电脑上就不需要在这个端口上有服务。


  (四)有关的代码

局域内有支持WEB的服务器,可以使用以下的PHP或ASP代码来唤醒。

没有WEB服务的,具备以下条件的,也可以通过任务计划每隔几分钟执行脚本来唤醒。

1、在外网上有一个WEB服务器,可以提交和读取开机关机的任务

2、在局域网内有一台开着的电脑,与要唤醒的电脑可以相互访问。

本人编写了一个脚本文件,来控制家里、办公室几台电脑的开启和关闭。



PHP代码


<?php

/*
http://www.depicus.com/wake-on-lan/woli.aspx

数据包的结构是由6组FF前缀+16次重复MAC地址组成

*/
ini_set('date.timezone','Asia/Shanghai');
$port=@$_GET['port'];
if (!is_numeric($port)) $port = '9';//外网UDP端口,内网映射UDP端口为7或9,指定端口主要是为了测试
$ip = '192.168.1.66';//123.tpddns.cn


//此处以 MAC地址为:1C-69-7A-26-0A-2F 为例,转换为16进制包的结果如下:

$str_hex="\xFF\xFF\xFF\xFF\xFF\xFF\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23 \x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B \x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79 \xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23 \x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B\x0D\x79\xAD\x23\x1C\x1B \x0D\x79\xAD\x23";

$handle = stream_socket_client('udp://'.$ip.':'.$port,$errno,$errstr);

if (!$handle) {
die('ERROR:'.$errno. '- '.$errstr.'\n');
}
fwrite($handle,$str_hex.'\n');
fclose($handle);

$date =new DateTime(); 
echo $date->format('Y-m-d H:i:s'); 
echo "<br/>udp://{$ip}:{$port}<br/>"
?>

OK...........


VBS代码

如果是WINDOWS环境且未安装PHP,可以使用VB的MSWINSOCK控件,没有安装的可以下载OCX文件后,复制到C:\Windows\SysWOW64\,然后以管理员身份打开CMD,运行:

Regsvr32.exe C:\Windows\SysWOW64\MSWinsock.ocx

注册后,同样使用C:\Windows\SysWOW64\WSCRIPT.exe可以运行以下代码(没找到64位的)

如果注册后运行出现 “类无法使用”错误,,则要在注册表上添加以下:

[HKEY_CLASSES_ROOT\Licenses\2c49f800-c2dd-11cf-9ad6-0080c7e7b78d]
@="mlrljgrlhltlngjlthrligklpkrhllglqlrk"



dim sock,mac,host,port

mac="0C91234644E1" 
host="192.168.1.2"
port=9


magic="FFFFFFFFFFFF" & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC & MAC

Set sock = CreateObject("MSWINSOCK.Winsock")
sock.Protocol = 1
sock.RemoteHost =host
sock.RemotePort = port
sock.SendData hex2bin(magic)
msgbox "OK"

function hex2bin(s)
 dim dom,elm
 set dom=createobject("microsoft.xmldom")
 set elm=dom.createelement("z")
 elm.datatype="bin.hex"
 elm.text=s
 hex2bin= elm.nodetypedvalue
 set elm=nothing
 set dom=nothing
end function