从Android向PC发送Wake on LAN数据包

问题描述

| 我的Android应用程序使用HTTP向用户自己的PC发送数据/从用户自己的PC检索数据,并且它与少数Beta测试人员都能正常工作。我现在需要考虑PC处于休眠状态的情况。 我以前从未做过此事,但我一直在Google上寻找有关WOL“魔术包”的信息以及一些用C语言编写的简单源(在客户端使用CAsyncSocket)。通过用户家庭网络上的wi-fi连接执行此操作可能相对简单,但理想情况下,我希望此操作可通过移动Internet进行(假设用户可以配置其家庭路由器以接受/转发数据包) 。 我猜我需要使用一些通用的Java网络代码,而且我一直在查看
java.net
。 此时,我无法确定应该使用whether1ѭ还是
java.net.DatagramSocket
。所以问题是,我是否以正确的方式来实现?我应该使用两种套接字类型中的哪一种(或者都足够)?非常感谢。     

解决方法

这是我过去使用的一些C#代码。转换成java并使用DatagramPacket发送应该相对容易
namespace WakeOnLan
{
    class Program
    {
        static void Main(string[] args)
        {

            byte[] mac = new byte[] { mac address goes here i.e 0x00,and so on };
            WakeUp(mac);
        }

        private static void WakeUp(byte[] mac)
        {
            //
            // WOL packet is sent over UDP 255.255.255.0:40000.
            //
            Console.WriteLine(\"Waking Up.......\");
            UdpClient client = new UdpClient();
            client.Connect(IPAddress.Broadcast,40000);

            //
            // WOL packet contains a 6-bytes trailer and 16 times a 6-bytes sequence containing the MAC address.
            //
            byte[] packet = new byte[17 * 6];

            //
            // Trailer of 6 times 0xFF.
            //
            for (int i = 0; i < 6; i++)
                packet[i] = 0xFF;

            //
            // Body of magic packet contains 16 times the MAC address.
            //
            for (int i = 1; i <= 16; i++)
                for (int j = 0; j < 6; j++)
                    packet[i * 6 + j] = mac[j];

            //
            // Submit WOL packet.
            //
            client.Send(packet,packet.Length);
            Console.WriteLine(\"Machine Woke Up....\");
        }
    }
}
希望这可以帮助     ,我不能为此付出太多的努力,因为它来自本网站 但这是唤醒类的Java版本:
public static final int PORT = 9;    

public static void main(String[] args) {

    if (args.length != 2) {
        System.out.println(\"Usage: java WakeOnLan <broadcast-ip> <mac-address>\");
        System.out.println(\"Example: java WakeOnLan 192.168.0.255 00:0D:61:08:22:4A\");
        System.out.println(\"Example: java WakeOnLan 192.168.0.255 00-0D-61-08-22-4A\");
        System.exit(1);
    }

    String ipStr = args[0];
    String macStr = args[1];

    try {
        byte[] macBytes = getMacBytes(macStr);
        byte[] bytes = new byte[6 + 16 * macBytes.length];
        for (int i = 0; i < 6; i++) {
            bytes[i] = (byte) 0xff;
        }
        for (int i = 6; i < bytes.length; i += macBytes.length) {
            System.arraycopy(macBytes,bytes,i,macBytes.length);
        }

        InetAddress address = InetAddress.getByName(ipStr);
        DatagramPacket packet = new DatagramPacket(bytes,bytes.length,address,PORT);
        DatagramSocket socket = new DatagramSocket();
        socket.send(packet);
        socket.close();

        System.out.println(\"Wake-on-LAN packet sent.\");
    }
    catch (Exception e) {
        System.out.println(\"Failed to send Wake-on-LAN packet: + e\");
        System.exit(1);
    }

}

private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
    byte[] bytes = new byte[6];
    String[] hex = macStr.split(\"(\\\\:|\\\\-)\");
    if (hex.length != 6) {
        throw new IllegalArgumentException(\"Invalid MAC address.\");
    }
    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;
}
当然,您需要修改它才能与android一起使用(需要很少的工作),但我发现它的效果比@Bear \的答案更好。     ,java.net.DatagramSocket可能会很好地工作,因为WoL不提供交付确认。令人怀疑的是,您能否使其在本地网络之外工作,因为WoL数据包是通过目标地址为目标计算机MAC地址的网络广播的,并且大多数路由器都设置为阻止广播数据包从WAN。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...