Alex
Alex

Reputation: 1575

NWConnection SSDP Discovery not receiving data

I'm trying to do an SSDP Discovery broadcast and unable to get reply data from NWConnection.receive.

Network.framework is relatively new and there is not a lot of info out there. What I'm missing here?

SSDP Discovery broadcast was sent and a UPnP device replied. (Wireshark screenshot below) enter image description here

    import Foundation
    import Network

    let connection = NWConnection(host: "239.255.255.250", port: 1_900, using: .udp)

    func sendBroadcast() {
        let message = """
            M-SEARCH * HTTP/1.1
            ST: ssdp:all
            HOST: 239.255.255.250:1900
            MAN: ssdp:discover
            MX: 1
            """.data(using: .utf8)

        connection.send(content: message, completion: .contentProcessed { error in
                if let error = error {
                    print("Send Error: \(error)")
                } else {
                    print("Broadcast sent")
                }
            }
        )
    }

    connection.stateUpdateHandler = { newState in
        switch newState {
        case .setup:
            print("Connection: Setup")
        case .preparing:
             print("Connection: Preparing")
        case .waiting:
            print("Connection: Waiting")
        case .ready:
            print("Connection: Ready")
            sendBroadcast()
        case .failed:
            print("Connection: Failed")
        case .cancelled:
            print("Connection: Cancelled")
        }
    }

    connection.receive(minimumIncompleteLength: 2, maximumLength: 4_096) { data, context, isComplete, error in
        /// This is never executed
        ///
        print(data ?? "", context ?? "", isComplete, error ?? "")
    }

    connection.viabilityUpdateHandler = { update in
        print(update)
    }

    connection.betterPathUpdateHandler = { path in
        print(path)
    }

    connection.start(queue: .main)

    RunLoop.main.run()

Upvotes: 2

Views: 1416

Answers (2)

Lance Samaria
Lance Samaria

Reputation: 19622

With UDP try this method instead:

connection.receiveMessage { (data, context, isComplete, error) in

    print(data ?? "", context ?? "", isComplete, error ?? "")
}

Here is a good example of it in use here

I had the opposite problem with TCP and was using connection.receiveMessage(...) and the same thing was happening -the callback was never entered. I posted a question in Apple Forums. It turns out with TCP you can only use:

connection.receive(minimumIncompleteLength: 1, maximumLength: 65535) { data, context, isComplete, error in
    
    print(data ?? "", context ?? "", isComplete, error ?? "")
}

An Apple Developer Technical Support Specialist named eskimo answered it here:

. TCP is not a message-oriented protocol, and thus

receiveMessage(…)

doesn’t make any sense. What you want is

receive(minimumIncompleteLength:maximumLength:completion:)

That being said, with UDP try connection.receiveMessage(…)

Upvotes: 0

Alex
Alex

Reputation: 1575

Turns out Network.framework does not support UDP Broadcasts yet (Feb 2019) https://forums.developer.apple.com/message/316357#316357

Upvotes: 3

Related Questions