网络唤醒应用仅适用于最近关闭的设备

Wake-on-Lan app only works for recently shutdown devices

我用 Kotlin 编写了一个小应用程序,它通过本地网络向智能电视发送一个 Magic Packet。我使用 this approach (code),用 Kotlin 重写(另外我硬编码了 IP 和 MAC 用于测试目的)。

当电视关闭时,我可以使用我的应用程序轻松重启它。一段时间后,它不再起作用了。

代码

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

fun main() {
   magicPacket("A8:23-FE:A0:5C:DB", "192.168.xx.xxx", 7)
}

    /**
     * Android:
     * Network interaction starting in new Thread!
     */
    fun magicPacket(mac: String, ip: String, PORT: Int = 7) {
        // throws IllegalThreadStateException without declaration
        //val t = thread {
        val packet = buildPacket(mac)
        val datagramSocket = DatagramSocket()
        try {
            datagramSocket.send(
                DatagramPacket(
                    packet,
                    packet.size,
                    InetAddress.getByName(ip),
                    PORT
                )
            )
            datagramSocket.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        //}
    }

    private fun buildPacket(mac: String): ByteArray {
        // prepare packet   (6 bytes header) (16 * 6 bytes MAC)
        val temp = ByteArray(6 + 6 * 16)
        val macBytes = ByteArray(6)
        for (i in 0..5) {
            temp[i] = 0xFF.toByte()
            macBytes[i] = mac.split(":", "-")[i].toInt(16).toByte()
        }
        for (i in 6 until temp.size step macBytes.size) System.arraycopy(
            macBytes,
            0,
            temp,
            i,
            macBytes.size
        )
        return temp
    }

我在代码中尝试了什么

我发现了什么

  1. WOL 并非在所有设备上都有效
  2. 电源状态可能很重要
  3. Wake On Lan无论如何都能唤醒设备,所以我认为问题出在应用程序上,而不是任何设置
  4. 所有网络 IP 和 MAC 都是静态的

发送wakeonlan数据包时,需要确保目标设备能够接收到数据包。

目前,您正在将数据包发送到设备的 IPv4 地址。

当您的计算机必须向 IPv4 地址发送数据包时,它需要知道其 MAC 地址。所以它询问网络“谁有 IPv4 192.168.2.32?告诉我你的 mac 地址”。由于您的电视已关机,因此它没有响应。

真正的 LAN 唤醒数据包永远不会发送,因为它不知道目标 mac 地址。

那么真正的问题就变成了,为什么关机后直接就可以了,这是因为你的OS有一个IPv4+mac地址的列表table,所以它可以快速发送数据包。您可以在 Windows

上使用命令 arp -av 查看此列表

请注意,当您的程序成功唤醒电视时显示“动态”,但未能唤醒电视时显示“无效”。

一个解决方案是将数据包发送到每个设备接收的广播 IPv4 地址。此 IPv4 地址通常以 .255 结尾,具有典型的消费者 IPv4 范围。