简体   繁体   English

局域网唤醒应用程序仅适用于最近关闭的设备

[英]Wake-on-Lan app only works for recently shutdown devices

I have written a small application in Kotlin which sends a Magic Packet to a smart tv over my local network.我在 Kotlin 中编写了一个小应用程序,它通过我的本地网络向智能电视发送一个魔术包。 I used this approach ( code ), rewritten in Kotlin (plus i hardcoded the IP and MAC for testing purposes).我使用了这种方法代码),用 Kotlin 重写(加上我硬编码了 IP 和 MAC 用于测试目的)。

When the tv is shutdown, i can easily restart it with my application.当电视关闭时,我可以很容易地用我的应用程序重新启动它。 After a while, that doesn't work anymore.一段时间后,这不再起作用了。

Code代码

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
    }

What i tried in code我在代码中尝试了什么

  • i changed port numbers (starting with random (11111, 55555, quick google search suggested ports 0, 7, 9) which all failed我更改了端口号(从随机(11111、55555、快速谷歌搜索建议的端口 0、7、9 开始)都失败了
  • sending not one but 10 to 100 packets发送不是一个而是 10 到 100 个数据包
  • i ran the app as a java (kotlin) project from Intellij on my PC aswell, same results我也在我的 PC 上将应用程序作为 Intellij 的 java (kotlin) 项目运行,结果相同

What i found out yet我发现了什么

  1. WOL doesn't work on every device WOL 并不适用于所有设备
  2. power states may be important电源状态可能很重要
  3. Wake On Lan manages to wake up the device no matter what, so i think the problem is the app, not any settings Wake On Lan无论如何都能唤醒设备,所以我认为问题在于应用程序,而不是任何设置
  4. All network IPs and MACs are static所有网络 IP 和 MAC 均为 static

When sending a wakeonlan packet, you need to make sure the target device can receive the packet.发送wakeonlan 数据包时,需要确保目标设备可以接收数据包。

At the moment, you are sending the packet to the IPv4 address of the device.目前,您正在将数据包发送到设备的 IPv4 地址。

When your computer has to send a packet to an IPv4 address, it needs to know its MAC address.当您的计算机必须向 IPv4 地址发送数据包时,它需要知道其 MAC 地址。 So it asks the network "Who has IPv4 192.168.2.32? Tell me your mac address".所以它会询问网络“谁拥有 IPv4 192.168.2.32?告诉我你的 MAC 地址”。 Since you TV is shutdown, it does not respond.由于您的电视已关闭,因此它没有响应。

The real wake on lan packet will never be send, as it des not know the destination mac address.永远不会发送真正的 LAN 唤醒数据包,因为它不知道目标 MAC 地址。

The real question then becomes, why does it work directly after shutting down, and the reason for this is that your OS keeps a list of IPv4+mac address table, so it can quickly send the packet out.那么真正的问题就变成了,为什么它在关闭后直接工作,原因是你的操作系统保存了一个IPv4+mac地址表列表,所以它可以快速发送数据包。 You can view this list with the command arp -av on Windows您可以在 Windows 上使用命令arp -av查看此列表

Note how it shows "dynamic" when your program successfully wakes the TV, but shows "invalid" when it fails to wake the TV up.请注意当您的程序成功唤醒电视时它如何显示“动态”,但当它未能唤醒电视时显示“无效”。

One solution for this, is sending the packet to the broadcast IPv4 address, which every devices receives.一种解决方案是将数据包发送到广播 IPv4 地址,每个设备都会收到该地址。 This IPv4 address typically ends with .255 with typical consumer IPv4 ranges.此 IPv4 地址通常以.255结尾,具有典型的消费者 IPv4 范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM