首页 > 解决方案 > 使用网络的 SSDP UPnP 发现

问题描述

我正在尝试通过发送 SSDP 发现数据包在我的网络中搜索 UPnP 设备。我可以发送它们,但我没有收到来自设备的响应,我不知道我错过了什么。也许这里有人可以帮助我。目标是不使用任何外部库(pods、spm、...)。

这是我所拥有的:

import UIKit
import Network

extension NWEndpoint.Port {
    static let ssdp: NWEndpoint.Port = 1_900
}

extension NWEndpoint.Host {
    static let ssdp: NWEndpoint.Host = "239.255.255.250"
}

class ViewController: UIViewController {
    private let parameters: NWParameters = {
        let parameters: NWParameters = .udp
        parameters.allowLocalEndpointReuse = true
        parameters.allowFastOpen = true

        return parameters
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .systemBackground

        do {
            try setupConnection()

        } catch {
            print(error.localizedDescription)
        }
    }

    private func setupConnection() throws {
        let endpoints: [NWEndpoint] = [
            .hostPort(host: .ssdp, port: .ssdp)
        ]

        let multicast = try NWMulticastGroup(for: endpoints)
        let group = NWConnectionGroup(with: multicast, using: parameters)

        group.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: true) { (message, content, isComplete) in
            print("Received message from \(String(describing: message.remoteEndpoint))")
        }

        group.stateUpdateHandler = { [weak viewController = self] (state) in
            guard let viewController = viewController else {
                return
            }

            switch state {
            case .setup:
                print("Setup")

            case .waiting(let error):
                let message = String(format: "Waiting: %@", error.localizedDescription)
                print(message)

            case .ready:
                print("Ready")
                viewController.send(to: group)

            case .failed(let error):
                let message = String(format: "Failed: %@", error.localizedDescription)
                print(message)

            case .cancelled:
                print("Cancelled")

            @unknown default:
                print("Unknown group state")
            }
        }

        group.start(queue: .main)
    }

    private func send(to group: NWConnectionGroup) {
        let message = "M-SEARCH * HTTP/1.1\r\nST: ssdp:all\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 1\r\n\r\n"
        let payload = message.data(using: .utf8)

        group.send(content: payload) { error in
            let message: String

            if let error = error {
                message = String(format: "Send completed with error %@", error.localizedDescription)

            } else {
                message = String(format: "Send completed")
            }

            print(message)
        }
    }
}

任何帮助表示赞赏!同时谢谢你。

编辑:这也不起作用

import UIKit
import Network

extension NWEndpoint.Port {
    static let ssdp: NWEndpoint.Port = 1_900
}

extension NWEndpoint.Host {
    static let ssdp: NWEndpoint.Host = "239.255.255.250"
}

class ViewController: UIViewController {
    private let connectionQueue = DispatchQueue(label: "Connection")
    private let listenerQueue = DispatchQueue(label: "Listener")

    private let parameters: NWParameters = {
        let parameters: NWParameters = .udp
        parameters.allowLocalEndpointReuse = true

        return parameters
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .systemBackground

        do {
            try setupConnection()

        } catch {
            print(error.localizedDescription)
        }
    }

    private func setupConnection() throws {
        let listener = try NWListener(using: parameters)
        listener.stateUpdateHandler = { state in
            print("l-state", state)
        }

        listener.newConnectionHandler = { (connection) in
            print("connection", connection)
        }

        listener.start(queue: listenerQueue)

        let connection = NWConnection(host: .ssdp, port: .ssdp, using: parameters)
        connection.stateUpdateHandler = { [weak viewController = self] state in
            print("c-state", state)

            guard let viewController = viewController else {
                return
            }

            switch state {
            case .ready:
                viewController.send(to: connection)

            default: return
            }
        }

        connection.start(queue: connectionQueue)
    }

    private func send(to connection: NWConnection) {
        let message = "M-SEARCH * HTTP/1.1\r\nSt: ssdp:all\r\nHost: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\r\nMX: 1\r\n\r\n"

        let payload = message.data(using: .utf8)
        connection.send(content: payload, completion: .contentProcessed { error in
            if let error = error {
                print(error.localizedDescription)
            } else {
                print("ok")
            }
        })

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

标签: iosswiftnetworkingupnpssdp

解决方案


推荐阅读