Java DatagramSocket 未接收到来自某些路由器的 UDP 广播
Java DatagramSocket not receiving UDP broadcast from some routers
我有一个 Android 客户端和纯 Java 服务器都在同一个子网上,我正在从客户端向服务器发送 UDP 广播数据包。对于某些路由器(Netgear、Cisco),服务器很乐意接收数据包,但对于我的华硕路由器,当服务器 machine 接收数据包时,服务器 DatagramSocket没有。
NB 在所有情况下,Wireshark 都会显示数据包正在到达服务器计算机。但是当使用华硕路由器时,DatagramSocket 似乎看不到它们。为了简单起见,服务器只有一个到路由器的以太网连接。
代码很标准。
客户:
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
socket.setSoTimeout(500); // 500 millis
while (isRunning()) {
final InetAddress broadcastAddress = getSubnetBroadcastAddress();
final DatagramPacket outboundPacket = new DatagramPacket(REQUEST_MESSAGE, REQUEST_MESSAGE.length, broadcastAddress, broadcastPort);
socket.send(outboundPacket);
}
} catch (IOException e) {
Log.i(TAG, "Beacon failed", e);
} finally {
if (socket != null) {
socket.close();
}
}
private InetAddress getSubnetBroadcastAddress() throws IOException {
final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final DhcpInfo dhcp = wifi.getDhcpInfo();
if (dhcp == null) {
// No successful DHCP request. Go with best effort.
Log.d(TAG, "#getBroadcastAddress - No DHCP info so using generic broadcast address");
return InetAddress.getByName("255.255.255.255");
}
final int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
final byte[] quads = new byte[4];
for (int k = 0; k < 4; k++) {
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
}
return InetAddress.getByAddress(quads);
}
服务器:
DatagramSocket socket = null;
try {
socket = new DatagramSocket(broadcastPort);
socket.setSoTimeout(LISTENING_TIMEOUT);
socket.setBroadcast(true);
while (keepRunning) {
try {
final byte[] buffer = new byte[1024];
final DatagramPacket receivedPacket = new DatagramPacket(buffer, buffer.length);
socket.receive(receivedPacket);
log.debug("Received packet : " + receivedPacket.toString());
} catch (SocketTimeoutException e) {
log.debug("#run BeaconRunnable socket timed out");
}
}
} catch (IOException e) {
log.warn("Error while receiving message", e);
if (socket != null) {
socket.close();
}
}
是什么导致 DatagramSocket 看不到 Asus 路由器的 UDP 广播数据包?
对于那些跟随..
上面的代码没有任何问题。
路由器配置没有问题。
规则已添加到 Windows 防火墙,阻止来自 public 连接的传入 UDP,并且华硕路由器出于某种原因被视为 public 连接。
禁用该规则让一切正常。
我有一个 Android 客户端和纯 Java 服务器都在同一个子网上,我正在从客户端向服务器发送 UDP 广播数据包。对于某些路由器(Netgear、Cisco),服务器很乐意接收数据包,但对于我的华硕路由器,当服务器 machine 接收数据包时,服务器 DatagramSocket没有。
NB 在所有情况下,Wireshark 都会显示数据包正在到达服务器计算机。但是当使用华硕路由器时,DatagramSocket 似乎看不到它们。为了简单起见,服务器只有一个到路由器的以太网连接。
代码很标准。
客户:
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
socket.setSoTimeout(500); // 500 millis
while (isRunning()) {
final InetAddress broadcastAddress = getSubnetBroadcastAddress();
final DatagramPacket outboundPacket = new DatagramPacket(REQUEST_MESSAGE, REQUEST_MESSAGE.length, broadcastAddress, broadcastPort);
socket.send(outboundPacket);
}
} catch (IOException e) {
Log.i(TAG, "Beacon failed", e);
} finally {
if (socket != null) {
socket.close();
}
}
private InetAddress getSubnetBroadcastAddress() throws IOException {
final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final DhcpInfo dhcp = wifi.getDhcpInfo();
if (dhcp == null) {
// No successful DHCP request. Go with best effort.
Log.d(TAG, "#getBroadcastAddress - No DHCP info so using generic broadcast address");
return InetAddress.getByName("255.255.255.255");
}
final int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
final byte[] quads = new byte[4];
for (int k = 0; k < 4; k++) {
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
}
return InetAddress.getByAddress(quads);
}
服务器:
DatagramSocket socket = null;
try {
socket = new DatagramSocket(broadcastPort);
socket.setSoTimeout(LISTENING_TIMEOUT);
socket.setBroadcast(true);
while (keepRunning) {
try {
final byte[] buffer = new byte[1024];
final DatagramPacket receivedPacket = new DatagramPacket(buffer, buffer.length);
socket.receive(receivedPacket);
log.debug("Received packet : " + receivedPacket.toString());
} catch (SocketTimeoutException e) {
log.debug("#run BeaconRunnable socket timed out");
}
}
} catch (IOException e) {
log.warn("Error while receiving message", e);
if (socket != null) {
socket.close();
}
}
是什么导致 DatagramSocket 看不到 Asus 路由器的 UDP 广播数据包?
对于那些跟随..
上面的代码没有任何问题。 路由器配置没有问题。
规则已添加到 Windows 防火墙,阻止来自 public 连接的传入 UDP,并且华硕路由器出于某种原因被视为 public 连接。
禁用该规则让一切正常。