【问题标题】:Detecting a client disconnecting with UDP using Network.framework使用 Network.framework 检测客户端与 UDP 断开连接
【发布时间】:2019-06-19 21:21:30
【问题描述】:

我正在尝试确定在使用 Network.framework 时 UDP 客户端何时停止向服务器发送数据包

我构建了一个小示例,演示了当客户端的连接被取消时,服务器无法将状态更改为.cancelled

示例客户端:

import Foundation
import Network

func sendMessage(on connection: NWConnection) {
    connection.send(content: "hello".data(using: .utf8), completion: .contentProcessed({error in
        if let error = error {
            print("error while sending hello: \(error)")
            return

        }

        connection.receiveMessage {data, context, isComplete, error in
            if let error = error {
                print("error while receiving reply: \(error)")
                return

            }

            connection.cancel()

        }

    }))
}

var connection: NWConnection = {
    let connection = NWConnection(
        to: .service(
            name: "Hello",
            type: "_test._udp",
            domain: "local",
            interface: nil
        ),
        using: .udp
    )

    connection.stateUpdateHandler = {newState in
        switch newState {
        case .ready:
            sendMessage(on: connection)
        case .failed(let error):
            print("client failed with error: \(error)")
        case .cancelled:
            print("Cancelled connection")
        default:
            break
        }
    }

    return connection
}()

connection.start(queue: DispatchQueue(label: "test"))

RunLoop.main.run()

示例服务器:

import Foundation
import Network

func receive(on connection: NWConnection) {
    connection.receiveMessage { (data, context, isComplete, error) in
        if let error = error {
            print(error)
            return

        }

        connection.send(content: "world".data(using: .utf8), completion: .contentProcessed({error in
            if let error = error {
                print("error while sending data: \(error)")
                return

            }

        }))

        receive(on: connection)

    }

}

var listener: NWListener = {
    let listener = try! NWListener(using: .udp)

    listener.service = NWListener.Service(name: "Hello", type: "_test._udp", domain: nil, txtRecord: nil)
    listener.newConnectionHandler = {newConnection in
        newConnection.stateUpdateHandler = {newState in
            switch newState {
            case .ready:
                receive(on: newConnection)
            case .failed(let error):
                print("client failed with error: \(error)")
            case .cancelled:
                print("Cancelled connection")
            default:
                break
            }
        }

        newConnection.start(queue: DispatchQueue(label: "new client"))


    }
    return listener
}()

listener.start(queue: DispatchQueue(label: "test"))

RunLoop.main.run()

在服务器运行的同时运行客户端时,客户端发送和接收一个数据包,然后被取消。客户端打印Connection cancelled。但是,服务器上 NWConnection 的状态并没有改变,当没有数据可以从客户端读取时,connection.receiveMessage 会静默失败。

我希望服务器连接的状态发生变化或receiveMessage 调用其完成处理程序,尽管没有数据存在(data 毕竟是Data?

所以,当在 Network.framework 上使用 UDP 服务器时,我不确定如何检测客户端何时停止发送数据包。我应该如何检测“断开连接”的客户端?

【问题讨论】:

标签: swift server-side-swift network.framework


【解决方案1】:

UDP 服务器无法通过网络获取有关 UDP 客户端是否已断开连接或离开的信息,除非客户端可能明确发送某种关于其断开状态的附加消息(通过 UDP、TCP 或其他侧通道) .所以没有什么可以改变 NWConnection 状态(除了服务器本身的某种问题)。

也许服务器可以在一些商定或协商的超时时间过去后假设断开连接,而没有某种活动。或数据包数,数据字节数。等等。然后关闭连接本身。

【讨论】:

    猜你喜欢
    • 2014-04-14
    • 2015-11-21
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    相关资源
    最近更新 更多