Многоадресный адрес Android уже используется

У меня есть простой поиск SSDP, но иногда я получаю ошибку Address in Use

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);, но все равно выдает ту же ошибку

Я посмотрел на этот SO, он предлагает то же самое, но в моем случае он работает не так, как ожидалось. Я получаю ту же ошибку.

Как я могу исправить эту проблему?


person arjun    schedule 27.08.2018    source источник


Ответы (1)


Эта строка:

multicast = новый MulticastSocket (ноль);

должен измениться на:

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.
person Cao Minh Vu    schedule 27.08.2018
comment
Я пробовал это раньше, ошибка java.net.SocketException: already bound - person arjun; 27.08.2018
comment
setReuseAddress принимает логическое значение - developer.android.com/reference/java/net / - person arjun; 27.08.2018
comment
да, обновился. Обратите внимание, что это также зависит от устройств. - person Cao Minh Vu; 27.08.2018
comment
Нет проблем с устройством. У меня есть другие приложения, которые без проблем запускают обнаружение SSDP. - person arjun; 27.08.2018