简述

使用在内网发起一个数据包来唤醒支持WOL的设备。
但是这有几个前提:

  1. 设备支持WOL

代码实现

使用UDP,设置广播模式,往目标或者直接全网段广播就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package net.liukai.tool;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class WakeOnLanTest {

public static void wakeUp(String macAddress) {
try {
byte[] macBytes = getMacBytes(macAddress);
byte[] magicPacket = new byte[102];
// 添加6个FF字节
for (int i = 0; i < 6; i++) {
magicPacket[i] = (byte) 0xff;
}
// 添加16次MAC地址
for (int i = 6; i < magicPacket.length; i += 6) {
System.arraycopy(macBytes, 0, magicPacket, i, 6);
}
// 创建用于发送UDP数据报的Socket
DatagramSocket socket = new DatagramSocket();
// 发送数据报到目标主机的255.255.255.255端口
DatagramPacket packet = new DatagramPacket(magicPacket, magicPacket.length, InetAddress.getByName("255.255.255.255"), 9);
socket.send(packet);
// 关闭Socket
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}

private static byte[] getMacBytes(String macAddress) throws IllegalArgumentException {
String[] hex = macAddress.split("(\\:|\\-)");
if (hex.length != 6) {
throw new IllegalArgumentException("Invalid MAC address.");
}
byte[] bytes = new byte[6];
try {
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid hex digit in MAC address.");
}
return bytes;
}

public static void main(String[] args) {
String macAddress = "11:22:33:44:55:66"; // 替换为目标设备的MAC地址
wakeUp(macAddress);
}
}

特殊情况

使用这种方式唤醒,如果是在双路由器的情况下,NAS的网络服务顺序会被改变。多次测试确实是这样,但是原理想不通。
原来默认网关出是是A路由器,使用代码后,就会成B路由器。使用synology官方的唤醒工具就没有这个问题。
为什么要用两个路由器,因为其中一个刷了固件,懂的都懂。
顺序变了有什么影响?当然有,默认B路由器的网走的不是常规网络,外部访问不了。
但是,如果NAS是使用了FRP,FRP的功能不受影响,因为FRP指定了内网IP和端口。