远程开机原理
远程开机简称WOL(Woke on LAN),它是通过局域网实现远程开机。我们只需知道某一台处于局域网计算机的MAC地址,结合一定的软件,就能实现远程开机。它的工作过程是这样的:局域网中的计算机处于关机状态,但它的网卡处于监控状态,等待网络开机的数据包。一旦收到该数据包,网卡就能打开主机电源实现开机。要唤醒某一台电脑必须知道该电脑的编号,在没有开机的状态下我们不可能通过 IP或主机名来区分计算机,但每一块网卡都有惟一的MAC地址,通过教师机向该网卡发出“Wake up”的数据包,该机虽然处于关机状态,但网卡上的芯片可以通过三芯连接线获得电源,从而处理数据包中的地址信息确定是否开机,如果确认就通过三芯连接线向计算机发出开机信号。
硬件要求
远程开机的硬件要求 远程开机并不是每一台计算机都能实现的,它对网卡、主板、电源都有要求。
网卡
网卡是实现远程开机的一个最重要的元素,不是所有网卡都支持远程开机。一些报价在50元左右的网卡因为成本有限,往往不支持远程开机。目前比较流行的STAR-901、STAR-902、D-Link530TX、联想LN-1068A等都支持远程开机。购买网卡时我们可以向经销商咨询。一般来说,支持远程开机的网卡都有三针的WOL接口(请见图1),并赠送一根三芯连接线,以便和主板相连接,同时也要注意一下产品说明书。对于不支持该功能的网卡可以购买相适应的远程开机模块,效果是一样的。
主板
主板不支持远程开机也是不行的。支持该功能的主板上一般都在PCI插槽附近有一个三芯插座用三芯连接线把网卡和主板连接起来。
要实现远程开机必须给网卡电源,由于计算机处于关机状态,一般不能通过PCI插槽给网卡供电,所以必须通过三芯连接线给网卡电流。而有些最新的主板(PCI2.2标准)在关机状态下能够给PCI电源,所以这种主板就没有必要设三芯插座了。
设置CMOS的相关参数
当然,我们还需要设置一下CMOS的相关参数。开机按下Delete键进入CMOS设置界面,找到“Power Management Setup”电源管理菜单,回车进入子菜单,找到“Wake up Events”,回车后找到“Wake up on LAN/Ring”选项,将“Disabled”改为“Enabled”。保存退出CMOS设置。
python代码实现
from optparse import OptionParser
import socket
import struct
def wake(addr, mac):
mac_data = []
for i in range(0, 12, 2):
mac_data.append(int(mac[i:i+2], 16))
packet = struct.pack("!BBBBBB", 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
packet_mac = struct.pack("!BBBBBB", *mac_data)
for i in range(0, 16):
packet += packet_mac
#print "len: ", len(packet), "data: ", packet
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
try:
s.sendto(packet, addr)
print "唤醒数据包发送完成", addr, mac
finally:
s.close()
def main():
usage = "%prog [options]"
parser = OptionParser(usage = usage)
parser.add_option("-a", "--addr", dest="addr", help="Boardcast address", metavar="255.255.255.255")
parser.add_option("-p", "--port", dest="port", help="Port", metavar="7")
parser.add_option("-m", "--mac", dest="mac", help="MAC address", metavar="FF-FF-FF-FF-FF-FF")
(options, args) = parser.parse_args()
if not options.mac:
parser.print_help()
return
addr = "255.255.255.255"
port = 7
mac = options.mac.replace("-", "")
if options.addr:
addr = options.addr
if len(mac) != 12:
print "无效的MAC地址: %s" % options.mac
return
if options.port:
port = int(options.port)
wake((addr, port), mac)
if __name__ == "__main__":
main()