我已经编写了这段代码来实现Wake On Lan:
InetAddress address = InetAddress.getByAddress(
new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff});
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, 7);
socket.send(packet);
但我明白了:
java.io.IOException: Permission denied
at gnu.java.nio.VMChannel.send(Native Method)
at gnu.java.nio.VMChannel.send(VMChannel.java:308)
at gnu.java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:261)
at java.net.DatagramSocket.send(DatagramSocket.java:659)
at com.MyApp.wakeonlan(MyApp.java:685)
问题似乎是广播地址,因为如果我更改为任何其他地址,则不会出现此错误。我怎么能避免它呢?我正在使用linux busybox,使用JamVM和GNU Classpath。
答案 0 :(得分:1)
现在已经很晚了,但这里是类路径0.99的补丁:
diff -aur a/native/jni/java-nio/gnu_java_nio_VMChannel.c b/native/jni/java-nio/gnu_java_nio_VMChannel.c
--- a/native/jni/java-nio/gnu_java_nio_VMChannel.c 2007-12-28 18:49:56.000000000 +0100
+++ b/native/jni/java-nio/gnu_java_nio_VMChannel.c 2012-08-14 08:49:38.000000000 +0200
@@ -868,6 +868,17 @@
elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ int n = 1;
+
+ if (*((uint32_t *) elems) == 0xFFFFFFFF)
+ {
+ if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "unable to set broadcast option");
+ return -1;
+ }
+ }
+
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = *((uint32_t *) elems);
sockaddr.sin_port = htons (port);
这解决了这个问题。