Android多播地址已在使用中

时间:2018-08-27 15:56:36

标签: java android multicast datagram ssdp

我有一个简单的SSDP搜索,但有时会收到“使用中的地址”错误

public void search(String service, CallbackContext callbackContext) throws IOException {
    final int SSDP_PORT = 1900;
    final int SSDP_SEARCH_PORT = 1901;
    final String SSDP_IP = "239.255.255.250";
    int TIMEOUT = 3000;

    InetSocketAddress srcAddress = new InetSocketAddress(SSDP_SEARCH_PORT);
    InetSocketAddress dstAddress = new InetSocketAddress(InetAddress.getByName(SSDP_IP), SSDP_PORT);

    // Clear the cached Device List every time a new search is called
    mDeviceList = new JSONArray();

    // M-Search Packet
    StringBuffer discoveryMessage = new StringBuffer();
    discoveryMessage.append("M-SEARCH * HTTP/1.1\r\n");
    discoveryMessage.append("HOST: " + SSDP_IP + ":" + SSDP_PORT + "\r\n");

    discoveryMessage.append("ST:"+service+"\r\n");
    //discoveryMessage.append("ST:ssdp:all\r\n");
    discoveryMessage.append("MAN: \"ssdp:discover\"\r\n");
    discoveryMessage.append("MX: 2\r\n");
    discoveryMessage.append("\r\n");
    System.out.println("Request: " + discoveryMessage.toString() + "\n");
    byte[] discoveryMessageBytes = discoveryMessage.toString().getBytes();
    DatagramPacket discoveryPacket = new DatagramPacket(discoveryMessageBytes, discoveryMessageBytes.length, dstAddress);

    // Send multi-cast packet
    MulticastSocket multicast = null;
    try {
        multicast = new MulticastSocket(null);
        multicast.bind(srcAddress);
        multicast.setTimeToLive(4);
        multicast.send(discoveryPacket);
    } finally {
        multicast.disconnect();
        multicast.close();
    }

    // Create a socket and wait for the response
    DatagramSocket wildSocket = null;
    DatagramPacket receivePacket;
    try {
        wildSocket = new DatagramSocket(SSDP_SEARCH_PORT);
        wildSocket.setSoTimeout(TIMEOUT);

        while (true) {
            try {
                receivePacket = new DatagramPacket(new byte[1536], 1536);
                wildSocket.receive(receivePacket);
                String message = new String(receivePacket.getData());   
                try {
                    JSONObject device = new JSONObject();
                    device.put("USN", parseHeaderValue(message, "USN"));
                    device.put("LOCATION", parseHeaderValue(message, "LOCATION"));
                    device.put("ST", parseHeaderValue(message, "ST"));
                    device.put("Server", parseHeaderValue(message, "Server"));
                    createServiceObjWithXMLData(parseHeaderValue(message, "LOCATION"), device);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (SocketTimeoutException e) {
                callbackContext.success(mDeviceList);
                break;
            }
        }
    } finally {
        if (wildSocket != null) {
            wildSocket.disconnect();
            wildSocket.close();
        }
    }
}

如何将其设置为动态端口而不是1901?

我尝试做multicast.setReuseAddress(true);,但仍然出现相同的错误

我看过this SO,它暗示了同样的事情,但就我而言,它没有按预期工作。我不断收到相同的错误。

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

此行:

  

multicast = new MulticastSocket(null);

应更改为:

multicast = new MulticastSocket();
multicast.setReuseAddress(true);
multicast.bind(srcAddress);    

这将取决于平台。如果getReuseAddress()返回false,则您的设备不支持。 https://developer.android.com/reference/java/net/DatagramSocket.html#setReuseAddress(boolean)

Note: This functionality is not supported by all existing platforms, so it is implementation specific whether this option will be ignored or not. However, if it is not supported then getReuseAddress() will always return false.