I am currently developing a java application that allows the user to
be able to turn on a computer remotely using Wake On Lan. I have got
the code working, however it is slightly tempromental. The MAC Address
and the IP Address is hard coded into the program at present for
testing purposes. I can quite happily shut the computer down and then
wake it back up again with my program once or twice on the trot but
then it stops working all together. Then will eventually start working
again without me changing any of the code.
I have also a script that wake a computer using Wake On Lan which
works every time without fail so I know that it is not a network
problem.
Below is the code that I am using in order to perform Wake On Lan.
package remoteshutdown;
import java.io.*;
import java.net.*;
public class WakeOnLan {
public void WOL() {
final int PORT = 9;
String ipStr = "10.11.12.123";
String macStr = "00:07:E9:93:18:EB";
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;
}
}
Any help in this matter would be highly appreciated.
Thank you
> InetAddress address = InetAddress.getByName(ipStr);
> DatagramPacket packet = new DatagramPacket(bytes,
>bytes.length, address, PORT);
> DatagramSocket socket = new DatagramSocket();
> socket.send(packet);
> socket.close();
The problem is a Datagram does not get guaranteed delivery. It is up
to you have some sort of confirm and retry.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
> public void WOL() {
> final int PORT = 9;
> String ipStr = "10.11.12.123";
> String macStr = "00:07:E9:93:18:EB";
Where did you learn sending this strange packet of 0s then 6 copies of
the target mac to 10.11.12.123:9 would wake a machine? Is that some
proprietary box?
I would think you might want to send the packet several times, perhaps
even until you have some indication the machine has arisen.
Hi all,
Thanks for the replies. i have just noticed something a bit strange.
If I shut the computer down and then run my program to wake it up
again it works every time without fail. If I leave the computer turned
off for about 10 minutes the computer won't wake again when I run the
program. Does anyone have any clues as to why this could be the case.
Where did you get your info on how to implement Wake on LAN?
The first thing I can see which won't work is your use of the computer's IP
address. A computer which is turned off has no IP address. Ethernet works by
delivering frames to an Ethernet MAC address, the Ethernet layer in the network
stack converts an IP address to a MAC address using ARP, which is cached.
Whilst the ARP for the powered-off machine is cached you can send your IP
datagram. However, when the cache times out an ARP request is sent out on the
wire asking "who has this IP address?". As no machine has that IP address
(hopefully it's not been reassigned by DHCP) then no response comes back and
the IP address cannot be converted to a MAC.
I've never used WoL, but a quick look at Wikipedia says that the packet needs to
be a broadcast frame, i.e. sent to the LAN broadcast address not to a specific
IP.
--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : n...@ion.le.ac.uk
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
Hi all, thanks for the replies.
Would the subnet mask be the broadcast address. If not how would I
find it out.
I have put the subnet mask into the program but it is now coming up
with an error which says:
java.net.BindException: Cannot assign requested address: Datagram send
failed
>
> Hi all, thanks for the replies.
>
> Would the subnet mask be the broadcast address. If not how would I
> find it out.
>
> I have put the subnet mask into the program but it is now coming up
> with an error which says:
> java.net.BindException: Cannot assign requested address: Datagram send
> failed
No, the broadcast address is the network address plus a "host" of all 1's,
almost the inverse of the netmask. From your posts it isn't clear what your
network is, you are using the the 10.0.0.0 class A private network but you
don't say whether you've subnet it.
10.0.0.0 would have a default netmask of 255.0.0.0, but is typically subnet to a
class C network with netmask 255.255.255.0. In your case I presume you have the
class C subnet 10.11.12.0 with netmask 255.255.255.0, in which case the
broadcast address is 10.11.12.255. In general, for any IP subnet, the part of
the address representing the host (i.e. the part the netmask masks) can only
have N-2 hosts because "host" 0 is the network address and host N-1 (all 1
bits) is the broadcast address.