网络唤醒全攻略:手把手教你编写远程开机脚本(附代码与排错指南)
目录导读(Table of Contents)
- 什么是网络唤醒(Wake-on-LAN)及其原理
- 编写网络唤醒脚本前的三大准备(硬件/BIOS/工具)
- 核心代码:跨平台(Windows/Linux/macOS)的WOL脚本编写实战
- 1 Python通用脚本(推荐)
- 2 Bash脚本(Linux/macOS)
- 3 PowerShell脚本(Windows)
- 脚本自动化进阶:从命令行到定时任务与远程API
- 高频问题排查(FAQ):为什么我的电脑叫不醒?
- 安全性与最佳实践
什么是网络唤醒及其原理

网络唤醒(Wake-on-LAN,简称WOL)是一种局域网技术,允许你通过发送特定的网络数据包(即“魔术包”)来远程启动已关闭或处于睡眠状态的电脑,其核心原理是:网卡在待机状态下仍然接收网络流量,一旦识别到目标MAC地址的特定帧(包含6字节的0xFF + 目标MAC重复16次),便会触发主板电源开机信号。
编写网络唤醒脚本前的准备
在写代码之前,一切未配置妥当的硬件都是白搭,请按以下清单检查:
- BIOS/UEFI设置:进入电源管理或高级选项,开启“Wake on LAN”或“Power On By PCI-E”选项(不同主板叫法不同)。
- 网卡驱动设置:在操作系统中,将网卡属性里的“唤醒魔术包”设为“启用”。
- 工具验证:先用现成的WOL工具(如
wakeonlan、depicus)手动测试是否能正常开机,如果手动测试失败,写脚本也是徒劳。 - 获取MAC地址:在命令行输入
ipconfig /all(Windows)或ifconfig -a/ip link(Linux/macOS),记录物理地址(如00:11:22:33:44:55)。
核心代码:跨平台的WOL脚本编写实战
1 Python通用脚本(推荐) Python具有极佳的跨平台性,且无需编译,以下脚本是行业最常用的范式:
import socket
import struct
import sys
def send_wol(mac_str: str, broadcast_ip: str = "255.255.255.255", port: int = 9):
# 去除MAC地址中的冒号或横线
mac = mac_str.replace(":", "").replace("-", "")
if len(mac) != 12:
raise ValueError("MAC地址格式错误")
# 构建魔术包:6字节的0xFF + 16次目标MAC
data = b'\xff' * 6 + bytes.fromhex(mac) * 16
# 创建UDP套接字,并允许广播发送
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.sendto(data, (broadcast_ip, port))
sock.close()
print(f"魔术包已发送至 {broadcast_ip}:{port} → {mac_str}")
if __name__ == "__main__":
# 命令行使用示例:python wol.py 00:11:22:33:44:55
if len(sys.argv) < 2:
print("用法: python wol.py <MAC地址> [广播IP] [端口]")
sys.exit(1)
mac_addr = sys.argv[1]
ip = sys.argv[2] if len(sys.argv) > 2 else "255.255.255.255"
send_wol(mac_addr, ip)
2 Bash脚本(Linux/macOS)
利用系统自带工具etherwake或直接使用perl/nc(Netcat)构造包,最简洁的是使用wakeonlan命令,但若需纯脚本,可借助python(同上)或以下bash+nc技巧:
#!/bin/bash
# 依赖: nc (netcat) 和 xxd, 如果没有安装,请先安装
MAC="00:11:22:33:44:55" # 更改此地址
BROADCAST="192.168.1.255"
# 构造魔术包数据
PACKET=$(printf 'f%.0s' {1..12} | xxd -r -p)
# 注意: 上述只是FF FF FF,实际需要重复MAC 16次,建议用Python或Perl更稳妥
# 这里推荐使用perl方案(内嵌于bash):
perl -e 'print pack("H*", "ff"x6 . "00:11:22:33:44:55"x16)' | nc -u -b $BROADCAST 9
注意:Bash端构造二进制数据易出错,若无特殊要求,强烈建议使用Python脚本,因为其代码可读性和健壮性远优于内嵌perl或字符串拼接。
3 PowerShell脚本(Windows)
Windows原生环境可用以下脚本(保存为wol.ps1):
param([string]$mac = "00:11:22:33:44:55")
$mac = $mac -replace '[-:]',''
$target = [byte[]](0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
for($i=0; $i -lt 16; $i++) {
for($j=0; $j -lt 6; $j++) {
$target += [Convert]::ToByte($mac.Substring($j*2,2),16)
}
}
$udp = New-Object System.Net.Sockets.UdpClient
$udp.EnableBroadcast = $true
$udp.Send($target, $target.Length, "255.255.255.255", 9) | Out-Null
Write-Host "WOL 数据包已发送至 $mac"
脚本自动化进阶:从命令行到定时任务与远程API
- 局域网内同一网段:广播地址必须填写目标机器所在的子网广播地址(例如
168.31.255),否则数据包无法跨路由转发。 - 跨网段(端口映射):若想从公网唤醒,需在路由器上设置“端口转发”(如UDP 9端口)到目标机器所在的局域网广播地址,但此操作有安全风险,建议使用VPN或仅内网使用。
- 定时唤醒:在Windows任务计划程序中调用
powershell -File wol.ps1;在Linux的cron中加入python3 wol.py MAC。 - 集成到智能家居:通过MQTT或HTTP API调用该脚本,可实现手机远程开机。
高频问题排查(FAQ)
- Q: 为什么脚本执行成功,但电脑没醒? A: 首先检查目标机是否插电(笔记本需接电源)、网线是否连接(Wi-Fi网卡不支持WOL),确认BIOS里的WOL选项是否在休眠/软关机(S5状态)下也开启,部分主板默认仅支持“关机待机”而不支持“休眠”。
- Q: 为什么广播地址填
255.255.255不行? A: 因为255.255.255是本地受限广播,通常不会跨路由器转发到具体网段,建议使用子网定向广播地址,例如168.1.255。 - Q: 为什么MAC地址正确,但是发给子网广播地址还是失败? A: 检查防火墙是否拦截UDP 9端口,Windows的防火墙可能在“公用网络”下丢弃广播包,你需要在防火墙规则中入站允许UDP 9端口,或将网络配置文件改为“专用”。
安全性与最佳实践
请将脚本中的MAC地址改为受信任的设备,由于魔术包是明文且无认证,任何人只要在局域网内知道MAC地址,就能唤醒你电脑,从而增加被物理入侵风险,最佳实践:
- 将脚本封装为受密码保护的Web API,并用HTTPS加密。
- 在路由器上设置静态IP与MAC绑定。
- 启用ACL(访问控制列表),仅允许特定IP的主机发送WOL数据包。
通过以上代码与配置,你可以用一份Python脚本轻松管理全家的设备,按模板修改MAC即可秒懂远程开机的精髓,若遇到“叫不醒”的情况,请参照FAQ逐步排查,八成的故障都源于BIOS与网卡驱动的忽略项。