Адрес многоадресной рассылки Android уже используется - PullRequest
0 голосов
/ 27 августа 2018

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

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

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

1 Ответ

0 голосов
/ 27 августа 2018

Эта строка:

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.
...