简体   繁体   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)
                
            }
        }
    }

}

Here I attached my UDP file that contains connections and listener of UDP.在这里,我附上了我的 UDP 文件,其中包含 UDP 的连接和侦听器。

When I send some data for the first time, it will send the data and receive the data.当我第一次发送一些数据时,它会发送数据并接收数据。

But when I send data again, then data will be sent, but I am not getting data second time and onwards.但是当我再次发送数据时,数据将被发送,但我不会第二次及以后获取数据。 Listner is not listning anymore. Listner 不再列出。 Data will be sent but listener is not listening.数据将被发送,但侦听器未在侦听。

If I close the application and run it again, same issue occurs.如果我关闭应用程序并再次运行它,也会出现同样的问题。 First time load the data (listener lister the data) but second time listener is not working.第一次加载数据(侦听器侦听数据)但第二次侦听器不起作用。

What is the issue in my code ?我的代码有什么问题? I was trying so much but not resolving the issue.我尝试了很多,但没有解决问题。 Please anyone that can solve my issue would be so grateful to me.请任何可以解决我的问题的人都会非常感谢我。

Thank you in advance.先感谢您。

In your function receive you are using the NWConnection.receiveMessage if you check the documentation here:如果您在此处查看文档,则在您的函数receive您正在使用NWConnection.receiveMessage

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

You'll see that it schedules a single receive completion handler.您会看到它调度了一个接收完成处理程序。 That means that you'll have to do something to trigger it again.这意味着你必须做一些事情才能再次触发它。 What I normally do is have a function like:我通常做的是有一个功能,如:

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
            }
        }
    }

That way, after processing the read, you end up setting up another single receive completion handler.这样,在处理读取之后,您最终会设置另一个单个接收完成处理程序。

If you want to see a full example, you can check my article on using Network.framework here:如果您想查看完整示例,可以在此处查看我关于使用Network.framework文章:

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

The example uses TCP instead of UDP, but it should give a general idea.该示例使用 TCP 而不是 UDP,但它应该给出一个大致的概念。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM