远程开机也被称为远程唤醒技术(Wake on Lan: WOL),是指可以通过局域网、互联网或者通讯网实现远程开机,无论目标主机离用户有多远、处于什么位置,只要其与发送命令主机可以通信,就能够被随时启动,该技术被现在的大多数主板与网卡所支持。
远程开机的实现主要依靠向目标主机发送特定格式的数据包,最初AMD公司推出的MagicPackage用于生成远程唤醒所需的特殊数据包,俗称魔术包(Magic Package)。MagicPackage技术只是AMD公司开发并推广的技术,尚未成为一项国际标准,但是该技术受到大多数网卡制造商的支持,因此具有远程唤醒功能的网卡都兼容这项技术。
1 远程唤醒的必备条件
远程唤醒只能依赖于主机硬件实现,任何用于远程控制的客户端软件都不能完成远程唤醒,因为这些软件在关机状态下是无法工作的。要实现远程唤醒功能需要满足以下几方面的条件:
1. 主板支持:要实现远程唤醒,目标主机的主板必须支持远程唤醒功能,能在电脑关机时为网卡供电。 目前(2002年以后)的大部分主板都支持这该功能;
2. 在CMOS中打开远程唤醒功能:开机时进入CMOS,并将“Pow Management Setup”的“Wake Up On Lan”或“Resume by Lan”项设置为“Enable”或“On”即可(作者在本文的实验机上并未找到该项设置,也未进行该项设置);
3. 网卡支持与设置:要实现远程唤醒,主机网卡也必须支持远程唤醒功能,大多数现代网卡都已支持该功能。在硬件支持的前提下还要打开网卡的远程唤醒功能才能实现唤醒,打开网卡的远程唤醒功能有不止以下两种方法:①.右击“我的电脑”并选择“管理”选项,在随后出现的“计算机管理”窗口中找到“设备管理”,在设备列表中找到“网络适配器”下的本地网卡(注意是有线网卡),右击本地网卡并选择“属性”,在弹出的对话框中选择“高级”页签,选择“Wake on Magic Package”或“网络唤醒”选项并将其值设置为“开启”,在同一个窗口中选择“电源管理”页签,在“允许设备唤醒计算机”以及“只允许幻数据包唤醒计算机”选项前打钩,点击【确定】按钮;②.在win7系统中进入“控制面板”->“网络和Internet”->“网络连接”,找到本地连接,右击“本地连接”并选择“属性”,在随后出现的“本地连接 属性”窗口中点击“网络”页签下的【配置】按钮,在随后出现的窗口的“高级”和“电源管理”页签中进行与方法1同样的设置,点击【确定】按钮;
4. 电源支持:主机必须连接电源供电,笔记本电脑必须插继电器。必须使用ATX电源,而且其+5V Standby电流必须比较大,根据Intel的建议,它需要在600mA以上;
5. 目标主机上一次必须正常关机:如果计算机上次是非正常关机(突然断电、强制关机或者关机时发生错误)有可能导致远程唤醒失败,因为一些网卡需要在计算机关机的时候复位一个标记,而这个动作只有在正常关机的时候才会发生;
6. 发送开机命令的主机必须能够与目标主机建立通信:如果发送广播魔术包,那么只要保证广播包能到达目标主机即可,如果发送的是定向包则需要局域网路由器的支持,需要在路由器中配置一个到目标主机的路由信息。
具备以上6个条件之后就可以向目标主机发送魔术包使其自动开机,在展示代码以前先对魔术包以及数据格式的转换进行介绍。
2 魔术包与编码转换
2.1 魔术包的组成
魔术包是用16进制表示的数据包,它由固定的前缀数据以及固定重复次数的目标主机MAC地址所组成。所谓固定前缀数据即6对“FF”,所谓固定重复次数即16次,也就是说魔术包是由12个“F”加重复16次的主机MAC地址组成,例如本文所用试验机的MAC地址为“28-D2-44-35-68-A7”,所以使该机远程开机的魔术包为:
1 | 0xFFFFFFFFFFFF28D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A7 |
在Windows系统中,主机的MAC地址可以通过在命令窗口中输入“ipconfig -all”命令查看。
2.2 魔术包的编码转换
在发送魔术包之前需要将魔术包的内容进行编码转换,将其转换为二进制格式的数据进行发送,每一个16进制数占用4bit,所以上文的MAC地址(0x28D2443568A7)经过转码之后的二进制结果为:0010 1000 1101 0010 0100 0100 0011 0101 0110 1000 1010 0111。
使用Java发送UDP广播包时需要将发送的数据存储到byte数组缓存中进行发送,所以需要将魔术包的二进制数据转换为byte数组。Java中一个byte类型数据的长度为8bit,而在魔术包中每一个16进制数占用4bit,所以需要将两个16进制数组合表示为一个Java中的byte类型数据,下文将以试验机MAC地址的前两个数“28” 为例来说明编码转换过程:
1.将第1个数转换为byte类型数据:(byte)2 => 0000 0010;
2.将第1个数的转换结果右移4bit:(byte)2 << 4 => 0010 0000;
3.将第2个数 转换为byte类型数据:(byte)8 => 0000 1000
4.将2步和第3步中得到的两个数进行逻辑或运算得到转换结果:(byte)2 << 4) | ((byte)8) => 0010 1000。
参照上述步骤将“0x28D2443568A7”转换为byte数组的结果如下所示:
在介绍完远程唤醒的概念、必备条件以及魔术包之后就可以开始用Java代码发送UDP魔术包,使得目标主机进行远程开机。
3 Java发送UDP广播包
使用Java代码进行数据编码转换以及发送UDP广播包实现电脑远程开机的的代码如下:
1 | package com.wakeonlan; |
4 参考与鸣谢
在本文写作的过程中参考了很多网络资源,其中参考了如下几篇文章,在此对所有作者的无私奉献表示衷心的感谢。
http://blog.csdn.net/a351945755/article/details/22578221
http://kuku789123.blog.163.com/blog/static/13616735120130894146519/