Java Soket 无法在 Raspberry Pi 上发送多播数据包
Java Soket cannot send multicast packet on Raspberry Pi
我尝试在 Raspberry Pi 中 运行 这段代码。套接字可以从多播组接收数据,但是在尝试发送数据时显示以下错误:
pi@raspberrypi:~ $ java Protocol
java.net.MulticastSocket@647e05
java.io.IOException: Cannot assign requested address
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:693)
at Protocol.getSensorData(Protocol.java:201)
at Protocol.main(Protocol.java:305)
代码如下:
import java.net.*;
import java.util.*;
public class Protocol {
private MulticastSocket socket = null;
private MulticastSocket socket_switchPanel = null;
String MULTICAST_ADDRESS = "";
int port = -1;
public Protocol(String NIC, boolean isByIP, String multcastAddress, int port) {
this.MULTICAST_ADDRESS = multcastAddress;
this.port = port;
try {
InetAddress dstAddr = InetAddress.getByName(MULTICAST_ADDRESS);
socket = new MulticastSocket(port);
InetSocketAddress socketAddress = new InetSocketAddress(MULTICAST_ADDRESS, port);
NetworkInterface ni = NetworkInterface.getByName(NIC);
socket.setReuseAddress(true);
socket.joinGroup(socketAddress, ni);
System.out.println(ni);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
if (socket != null) {
socket.close();
}
}
}
public void close_socket() {
if (socket != null) {
socket.close();
}
}
public Integer getSensorData() {
byte[] msg = new byte[]{
(byte) 0xAB, 0x04, (byte) 0x82, (byte) 0xCD, 0x00, (byte) 0x01};
try {
// get the IP address
InetAddress dstAddr = InetAddress.getByName(MULTICAST_ADDRESS);
final DatagramPacket out = new DatagramPacket(msg, msg.length, dstAddr, port);
socket.send(out);
// receive data until timeout or stop prematurely on users' request
try {
// process multi cast response(s)
final byte[] inputBuffer = new byte[30];
final DatagramPacket in = new DatagramPacket(inputBuffer, inputBuffer.length);
socket.setSoTimeout(500);
socket.receive(in);
byte[] data = in.getData();
return 1;
} catch (Exception ste) {
}
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
public static void main(String[] args) {
// tring NIC, boolean isByIP, String multcastAddress, int port
Protocol dc = new Protocol("wlan0",
false,
"ff12:00:00:00:4479:00:00:00",
50000);
int ab = dc.getSensorData();
System.out.println(ab);
return;
}
}
您的 java 可能正在获取 IP V4 而不是 IP V6(就像您的多播地址似乎指向的那样)。尝试从
开始
-Djava.net.preferIPv6Addresses=true
通常这种情况发生在 java 更喜欢 v6 而不是 v4 的情况下,但这里可能有特殊情况。或者,您只是使用了一个无效的多播地址(查看 https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml#ipv6-scope 似乎以 ff12
开头的地址对 ipv6 多播地址无效)。
我找到了解决办法。您必须禁用其他接口。例如,如果您使用 WIFI 发送多播消息。您可以使用禁用 eth0
ifconfig eth0 down
。请注意,在 PI 重新启动后,eth0 会再次上线。
我尝试在 Raspberry Pi 中 运行 这段代码。套接字可以从多播组接收数据,但是在尝试发送数据时显示以下错误:
pi@raspberrypi:~ $ java Protocol
java.net.MulticastSocket@647e05
java.io.IOException: Cannot assign requested address
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:693)
at Protocol.getSensorData(Protocol.java:201)
at Protocol.main(Protocol.java:305)
代码如下:
import java.net.*;
import java.util.*;
public class Protocol {
private MulticastSocket socket = null;
private MulticastSocket socket_switchPanel = null;
String MULTICAST_ADDRESS = "";
int port = -1;
public Protocol(String NIC, boolean isByIP, String multcastAddress, int port) {
this.MULTICAST_ADDRESS = multcastAddress;
this.port = port;
try {
InetAddress dstAddr = InetAddress.getByName(MULTICAST_ADDRESS);
socket = new MulticastSocket(port);
InetSocketAddress socketAddress = new InetSocketAddress(MULTICAST_ADDRESS, port);
NetworkInterface ni = NetworkInterface.getByName(NIC);
socket.setReuseAddress(true);
socket.joinGroup(socketAddress, ni);
System.out.println(ni);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
if (socket != null) {
socket.close();
}
}
}
public void close_socket() {
if (socket != null) {
socket.close();
}
}
public Integer getSensorData() {
byte[] msg = new byte[]{
(byte) 0xAB, 0x04, (byte) 0x82, (byte) 0xCD, 0x00, (byte) 0x01};
try {
// get the IP address
InetAddress dstAddr = InetAddress.getByName(MULTICAST_ADDRESS);
final DatagramPacket out = new DatagramPacket(msg, msg.length, dstAddr, port);
socket.send(out);
// receive data until timeout or stop prematurely on users' request
try {
// process multi cast response(s)
final byte[] inputBuffer = new byte[30];
final DatagramPacket in = new DatagramPacket(inputBuffer, inputBuffer.length);
socket.setSoTimeout(500);
socket.receive(in);
byte[] data = in.getData();
return 1;
} catch (Exception ste) {
}
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
public static void main(String[] args) {
// tring NIC, boolean isByIP, String multcastAddress, int port
Protocol dc = new Protocol("wlan0",
false,
"ff12:00:00:00:4479:00:00:00",
50000);
int ab = dc.getSensorData();
System.out.println(ab);
return;
}
}
您的 java 可能正在获取 IP V4 而不是 IP V6(就像您的多播地址似乎指向的那样)。尝试从
开始-Djava.net.preferIPv6Addresses=true
通常这种情况发生在 java 更喜欢 v6 而不是 v4 的情况下,但这里可能有特殊情况。或者,您只是使用了一个无效的多播地址(查看 https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml#ipv6-scope 似乎以 ff12
开头的地址对 ipv6 多播地址无效)。
我找到了解决办法。您必须禁用其他接口。例如,如果您使用 WIFI 发送多播消息。您可以使用禁用 eth0
ifconfig eth0 down
。请注意,在 PI 重新启动后,eth0 会再次上线。