开源项目
https://github.com/Florianisme/WakeOnLan/
发送按钮时间
public void onClick() {
try {
WolSender.sendWolPacket(device);
Toast.makeText(this, getString(R.string.wol_toast_sending_packet, device.name), Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e(this.getClass().getName(), "Error while sending WOL Packet", e);
}
}
public class WolSender {
public static final Executor EXECUTOR = Executors.newSingleThreadExecutor();
public static void sendWolPacket(Device device) {
Runnable sendWolRunnable = new Runnable() {
@Override
public void run() {
sendPacket(device.broadcastAddress);
new BroadcastHelper().getBroadcastAddress().ifPresent(inetAddress -> sendPacket(inetAddress.getHostAddress()));
}
private void sendPacket(String broadcastAddress) {
if (Strings.isNullOrEmpty(broadcastAddress)) {
return;
}
WolSender封装
public class WolSender {
public static final Executor EXECUTOR = Executors.newSingleThreadExecutor();
public static void sendWolPacket(Device device) {
Runnable sendWolRunnable = new Runnable() {
@Override
public void run() {
sendPacket(device.broadcastAddress);
new BroadcastHelper().getBroadcastAddress().ifPresent(inetAddress -> sendPacket(inetAddress.getHostAddress()));
}
private void sendPacket(String broadcastAddress) {
if (Strings.isNullOrEmpty(broadcastAddress)) {
return;
}
try {
DatagramPacket packet = PacketBuilder.buildMagicPacket(broadcastAddress, device.macAddress, device.port, device.secureOnPassword);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
} catch (Exception e) {
Log.e(this.getClass().getName(), "Error while sending magic packet: ", e);
}
}
};
EXECUTOR.execute(sendWolRunnable);
}
}
核心代码PacketBuilder.java中,数据包封装机udp发送广播
static DatagramPacket buildMagicPacket(String broadcastAddress, String macAddress, int port, @Nullable String secureOnPassword) throws UnknownHostException {
byte[] macBytes = getMacBytes(macAddress);
byte[] secureOnPasswordBytes = getSecureOnPasswordBytes(secureOnPassword);
// Packet is 6 times 0xff, 16 times MAC Address of target and 0, 4 or 6 character password
byte[] bytes = new byte[6 + (16 * macBytes.length) + secureOnPasswordBytes.length];
// Append 6 times 0xff
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
// Append MAC address 16 times
for (int i = 0; i < 16; i++) {
appendMacAddress(macBytes, bytes, i);
}
// Append Password
System.arraycopy(secureOnPasswordBytes, 0, bytes, bytes.length - secureOnPasswordBytes.length, secureOnPasswordBytes.length);
InetAddress address = InetAddress.getByName(broadcastAddress);
return new DatagramPacket(bytes, bytes.length, address, port);
}
远程开启家里机器思路
需解决需要的时候再开机,不需要的时候机器处于关机状态
-
申请公网带宽
-
内网挂一个低功耗设备,树莓派?手机?
2.1 内部部署一个ip更新通知服务,检测到自己的公网ip发生变动,发个邮件给自己的邮箱
2.2 光猫及路由器作端口映射,把低功耗设备上的开机服务暴露出来,ssl+一些认证技术
-
PC机打开BIOS "Power ON By PCI-E"开关
-
PC机接上局域网网线
直接花钱的方案
购买成品支持wol的开机棒
todesk似乎有个手机app,原理估计类似
远程桌面技术
-
todesk
-
向日葵
-
自己搭建vnc,暴露端口