1

我有一个简单的 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,它暗示了同样的事情,但在我的情况下,它没有按预期工作。我不断收到同样的错误。

我该如何解决这个问题?

4

1 回答 1

0

这一行:

多播 = 新的 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.
于 2018-08-27T16:05:56.770 回答