简体   繁体   English

Java DatagramSocket未从某些路由器接收UDP广播

[英]Java DatagramSocket not receiving UDP broadcast from some routers

I have an Android client and plain Java server both on the same subnet and I am sending UDP broadcast packets from client to server. 我在同一子网中有一个Android客户端和普通Java服务器,并且正在从客户端向服务器发送UDP广播数据包。 With some routers (Netgear, Cisco) the server happily receives the packets, but for my Asus router while the server machine receives the packets the server DatagramSocket doesn't. 使用某些路由器(Netgear,Cisco),服务器可以愉快地接收数据包,但是对于我的华硕路由器,当服务器计算机接收数据包时,服务器DatagramSocket却不能。

NB In all cases, Wireshark shows that the packets are getting to the server machine. 注意:在所有情况下,Wireshark都会显示数据包正在到达服务器计算机。 But when using the Asus router the DatagramSocket doesn't seem to see them. 但是当使用华硕路由器时,DatagramSocket似乎看不到它们。 To keep things simple the server only has an ethernet connection to the router. 为简单起见,服务器仅与路由器建立以太网连接。

The code is pretty standard. 该代码是非常标准的。

Client: 客户:

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);
}

Server: 服务器:

    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();
        }
    }

What's causing the DatagramSocket to not see the UDP broadcast packets with the Asus router? 是什么导致DatagramSocket无法通过Asus路由器看到UDP广播数据包?

For those that follow .. 对于那些跟随..

There is nothing wrong with the code above. 上面的代码没有错。 There was nothing wrong with the router config. 路由器配置没有问题。

A rule had been added to Windows Firewall that blocked incoming UDP from public connections and the Asus router for some reason was deemed to be a public connection. Windows防火墙中添加了一个规则,该规则阻止来自公共连接的传入UDP,并且出于某种原因,华硕路由器被视为公共连接。

Disabling that rule let everything work. 禁用该规则将使一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM