2011-04-15 55 views
5

我的Android應用程序使用HTTP向用戶自己的PC發送數據/從用戶自己的PC檢索數據,並且與少數測試者一起工作良好。我現在需要考慮個人電腦冬眠的情況。發送從局域網喚醒LAN數據包到個人電腦

我從來沒有這樣做過,但我已經搜索了一下關於WOL'magic packet'和一些用C語言編寫的簡單源碼(在客戶端使用CAsyncSocket)。通過用戶家庭網絡上的Wi-Fi連接做到這一點很可能是相對直接的,但理想情況下,我希望通過移動互聯網工作(假設用戶可以配置其家庭路由器接受/轉發數據包)。

我猜我需要使用一些通用的Java網絡代碼,我一直在尋找java.net

在這一點上,我不能決定我是否應該使用java.net.Socketjava.net.DatagramSocket。所以問題是,我是否正確地接近了這種方式,以及我應該使用哪種套接字類型(或者兩者都足夠)?非常感謝。

+0

從我記得,它可以是任何東西:UDP,ICMP,TCP只要魔法在數據包中,但數據報應該更容易編程。困難的部分將是找到一種方法,使其工作在無線上;儘管在有線網絡上它非常可靠。 – 2011-04-15 21:07:24

+0

我連接到家庭網絡後,在市場商店中使用了多個應用程序,通過無線網絡喚醒了我的電腦。因爲我沒有正確配置我的路由器,因爲它沒有將數據包轉發給Nat後面的計算機,所以我沒有太多的運氣在網上做。 – Bear 2011-04-15 21:31:19

回答

10

這是我以前用過的一些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...."); 
     } 
    } 
} 

希望這有助於

+0

謝謝。您的代碼示例與我找到的C代碼類似,但稍微簡潔一些。轉換爲Java並不需要太多工作,我可以將代碼的UdpClient部分轉換爲DatagramSocket,只需添加幾行代碼。 – Squonk 2011-04-16 02:53:03

2

由於WoL沒有提供傳送確認,所以java.net.DatagramSocket可能會工作得很好。由於WoL數據包是通過網絡廣播的,目標地址是目標計算機的MAC地址,並且大多數路由器都設置爲阻止來自廣域網的廣播數據包,所以您是否能夠在本地網絡外部工作是值得懷疑的。

+0

感謝您的回覆。我使用Java的Bear代碼版本爲我的LAN工作。我想我可能可以通過使用端口轉發從外部工作,但我還沒有測試過它。我會看看會發生什麼。 – Squonk 2011-04-16 03:11:02

11

我不能從這個site

花太多它的信用作爲其發送但這醒來的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, 0, 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(需要很少的工作)工作,但我發現它比@Bel的答案更好。

+0

謝謝。我能夠讓熊的例子工作,但我可能會嘗試您發佈的代碼來比較兩者。 – Squonk 2012-12-01 00:58:00

+0

我還會注意到,我在OSX 10.8上遇到了端口9的問題,我不得不使用echo端口(7)讓Mac喚醒。 – 2012-12-04 22:21:24

+0

我只是想知道爲什麼這個作品不管我使用哪個端口..?端口7,9,11999,無論什麼.. – pootzko 2014-01-11 12:13:28