SSDP discovery - address in use

I'm using the Network framework to perform SSDP discovery for UPnP devices. The multicast entitlement is set, and discovery is working fine, except when another application is also using port 1900. In that case the following errors are given (this is in a catalyst app on macOS, the behavior on a physical iPhone is the same):

[] nw_path_evaluator_evaluate NECP_CLIENT_ACTION_ADD error [48: Address already in use]
[] nw_path_create_evaluator_for_listener nw_path_evaluator_evaluate failed
[listener] nw_listener_start_on_queue [L1] nw_path_create_evaluator_for_listener failed
[connection_group] nw_connection_group_handle_listener_state_change [G1] listener failed with error

Is it possible that multiple applications connect on the same port?

Here's the relevant code from the discovery class I'm using:

public class SSDPDiscovery {
    enum SSDPMessageType {
        case searchResponse
        case availableNotification
        case updateNotification
        case unavailableNotification
    }

    private let multicastGroupAddress = "239.255.255.250"
    private let multicastUDPPort: UInt16 = 1900
    private var multicastGroup: NWMulticastGroup?
    private var connectionGroup: NWConnectionGroup?
    private var types = [String]()
    
    func startDiscovery(forTypes types: [String]) throws {
        guard multicastGroup == nil else { throw UPnPError.alreadyConnected }
        let multicastGroup = try NWMulticastGroup(for:[.hostPort(host: .init(multicastGroupAddress), port: .init(integerLiteral: multicastUDPPort))])
        let params = NWParameters.udp
        params.allowLocalEndpointReuse = true
        let connectionGroup = NWConnectionGroup(with: multicastGroup, using: params)
        
        connectionGroup.stateUpdateHandler = { [weak self] (newState) in
            Logger.swiftUPnP.debug("Connection group entered state \(String(describing: newState))")
            
            switch newState {
            case let .failed(error):
                Logger.swiftUPnP.error("\(error.localizedDescription)")
            case .cancelled:
                self?.multicastGroup = nil
                self?.connectionGroup = nil
            default:
                break
            }
        }

        connectionGroup.setReceiveHandler(maximumMessageSize: 65535, rejectOversizedMessages: true) { (message, content, isComplete) in
            if let content = content {
                self.processData(content)
            }
        }
        
        connectionGroup.start(queue: .main)
        
        self.types = types
        self.multicastGroup = multicastGroup
        self.connectionGroup = connectionGroup
    }
    
    func stopDiscovery() {
        guard let connectionGroup = connectionGroup else { return }

        connectionGroup.cancel()
        multicastGroup = nil
        self.connectionGroup = nil
        types = []
    }
}

This is a known bug. See this thread. The workaround is to use BSD Sockets )-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the clarification, reverted to CocoaAsyncSocket for now.

SSDP discovery - address in use
 
 
Q