1

I have a simple SSDP search, but sometimes I get a Address in Use error

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

How can I set it to a dynamic port, instead of 1901?

I tried doing multicast.setReuseAddress(true); but it still gives the same error

I looked at this SO, it suggests the same thing but in my case it doesn't work as expected. I keep getting the same error.

How can I fix this issue?

arjun
  • 1,594
  • 16
  • 33

1 Answers1

0

This line:

multicast = new MulticastSocket(null);

should change to:

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

This will depend on platform. If getReuseAddress() return false, your device does not support. 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.
Cao Minh Vu
  • 1,900
  • 1
  • 16
  • 21