簡體   English   中英

Swift UDP 連接問題

[英]Swift UDP Connection Issue

protocol UDPListener {
    func handleResponse(_ client: UDPConnection, data: Data)
}

class UDPConnection{
    
    var connection: NWConnection?
    var listner: NWListener?
    var delegate: UDPListener?

    let parameters = NWParameters.udp
    
    // for connect with device
    func connect(withHost: NWEndpoint.Host, port: NWEndpoint.Port) {
        parameters.allowLocalEndpointReuse = true
        
        self.connection = NWConnection(host: withHost, port: port, using: parameters)
        self.connection?.stateUpdateHandler = { (newState) in
            switch (newState) {
            case .ready:
                print("connection ready")
            case .setup:
                print("connectionsetup")
            case .cancelled:
                print("connectioncancelled")
            case .preparing:
                print("connection Preparing")
            default:
                print("connection waiting or failed")
                
            }
        }
        self.connection?.start(queue: .global())
    }
    
    // for sending UDP string
    func sendUDP(_ content: String) {
        let contentToSendUDP = content.data(using: String.Encoding.utf8)
        self.connection?.send(content: contentToSendUDP, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
            if (NWError == nil) {
                print("Data was sent to UDP")
            } else {
                print("ERROR SEND! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
            }
        })))
    }
    
    //for sending UDP data
    func sendUDP(_ content: Data) {
        self.connection?.send(content: content, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
            if (NWError == nil) {
                print("Data was sent to UDP")
            } else {
                print("ERROR Send! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
            }
        })))
    }
    
    //////////////// UDP LISTNER /////////////////////

    func listenUDP(port: NWEndpoint.Port) {
        do {
            parameters.allowLocalEndpointReuse = true
            
            self.listner = try NWListener(using: parameters, on: port)
            self.listner?.stateUpdateHandler = {(newState) in
                switch newState {
                case .ready:
                    print("Listner ready")
                case .failed:
                    print("Listner failed")
                case .cancelled:
                    print("Listner cancelled")
                default:
                    break
                }
            }
            self.listner?.newConnectionHandler = {(newConnection) in
                newConnection.stateUpdateHandler = {newState in
                    switch newState {
                    case .ready:
                        print("new connection establish")
                        self.receive(on: newConnection)
                    case .failed:
                        print("new connection failed")
                    case .cancelled:
                        print("new connection cancelled")
                    default:
                        break
                    }
                }
                newConnection.start(queue: DispatchQueue(label: "new client"))
            }
        } catch {
            print("unable to create listener")
        }
        self.listner?.start(queue: .global())
    }
    
    func receive(on connection: NWConnection) {
        connection.receiveMessage { (data, context, isComplete, error) in
            if !isComplete {
                print("Not Complete")
            }
            if let error = error {
                print("Error in REceive: - ",error)
                return
            }
            if let data = data, !data.isEmpty {
//                let backToString = String(decoding: data, as: UTF8.self)
//                print("Received Data: ",backToString)
                
                guard self.delegate != nil else {
                    print("Error Receive: UDPClient response handler is nil")
                    return
                }
                
                print("Data receive in UDPConenction;")
                self.delegate?.handleResponse(self, data: data)
                
            }
        }
    }

}

在這里,我附上了我的 UDP 文件,其中包含 UDP 的連接和偵聽器。

當我第一次發送一些數據時,它會發送數據並接收數據。

但是當我再次發送數據時,數據將被發送,但我不會第二次及以后獲取數據。 Listner 不再列出。 數據將被發送,但偵聽器未在偵聽。

如果我關閉應用程序並再次運行它,也會出現同樣的問題。 第一次加載數據(偵聽器偵聽數據)但第二次偵聽器不起作用。

我的代碼有什么問題? 我嘗試了很多,但沒有解決問題。 請任何可以解決我的問題的人都會非常感謝我。

先感謝您。

如果您在此處查看文檔,則在您的函數receive您正在使用NWConnection.receiveMessage

https://developer.apple.com/documentation/network/nwconnection/3020638-receivemessage

您會看到它調度了一個接收完成處理程序。 這意味着你必須做一些事情才能再次觸發它。 我通常做的是有一個功能,如:

private func setupReceive() {
        connection.receive(minimumIncompleteLength: 1, maximumLength: MTU) { (data, _, isComplete, error) in
            if let data = data, !data.isEmpty {
                let message = String(data: data, encoding: .utf8)
                print("connection \(self.id) did receive, data: \(data as NSData) string: \(message ?? "-")")
                self.send(data: data)
            }
            if isComplete {
                self.connectionDidEnd()
            } else if let error = error {
                self.connectionDidFail(error: error)
            } else {
                self.setupReceive() // HERE I SET THE RECEIVE AGAIN
            }
        }
    }

這樣,在處理讀取之后,您最終會設置另一個單個接收完成處理程序。

如果您想查看完整示例,可以在此處查看我關於使用Network.framework文章:

https://rderik.com/blog/building-a-server-client-aplication-using-apple-s-network-framework/

該示例使用 TCP 而不是 UDP,但它應該給出一個大致的概念。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM