将 NWConnection 用于长时间运行的 TCP 套接字的正确方法 [英] Correct way to use NWConnection for long-running TCP socket

查看:147
本文介绍了将 NWConnection 用于长时间运行的 TCP 套接字的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一整天都在与 NWConnection 斗争,以在长时间运行的 TCP 套接字上接收数据.由于缺乏文档,我在给自己造成以下错误后终于让它工作了:

I've been fighting with NWConnection to receive data on a long-running TCP socket all day. I've finally got it working after inflicting the following errors on myself due to lack of documentation:

  1. 数据不完整(因为只调用了一次接收)
  2. 乱序获取 TCP 数据(由于从计时器轮询"接收...导致多个同时关闭以等待获取数据).
  3. 遭受无限循环(由于在接收后重新启动接收而不检查isComplete"Bool——一旦套接字从另一端终止,这是......坏......非常糟糕).

我所学到的总结:

  1. 一旦您处于 .ready 状态,您就可以调用接收...一次且仅一次
  2. 一旦您收到一些数据,您就可以再次调用接收...但前提是您仍处于 .ready 状态并且 isComplete 为 false.

这是我的代码.我认为这是对的.但如果有误,请告诉我:

Here's my code. I think this is right. But if it's wrong please let me know:

    queue = DispatchQueue(label: "hostname", attributes: .concurrent)
    let serverEndpoint = NWEndpoint.Host(hostname)
    guard let portEndpoint = NWEndpoint.Port(rawValue: port) else { return nil }
    connection = NWConnection(host: serverEndpoint, port: portEndpoint, using: .tcp)
    connection.stateUpdateHandler = { [weak self] (newState) in
        switch newState {
        case .ready:
            debugPrint("TcpReader.ready to send")
            self?.receive()
        case .failed(let error):
            debugPrint("TcpReader.client failed with error \(error)")
        case .setup:
            debugPrint("TcpReader.setup")
        case .waiting(_):
            debugPrint("TcpReader.waiting")
        case .preparing:
            debugPrint("TcpReader.preparing")
        case .cancelled:
            debugPrint("TcpReader.cancelled")
        }
    }

func receive() {  
    connection.receive(minimumIncompleteLength: 1, maximumLength: 8192) { (content, context, isComplete, error) in
        debugPrint("\(Date()) TcpReader: got a message \(String(describing: content?.count)) bytes")
        if let content = content {
            self.delegate.gotData(data: content, from: self.hostname, port: self.port)
        }
        if self.connection.state == .ready && isComplete == false {
            self.receive()
        }
    }
}

推荐答案

我认为您可以多次使用短时间连接.例如,客户端连接到主机并要求主机做某事,然后告诉主机关闭连接.主机切换到等待模式以准备新的连接.见下图.

I think you can use a short time connection many times. For example a client connects to the host and asks the host to do something and then tells the host to shutdown the connection. The host switches to the waiting mode to ready a new connection. See the diagram below.

这篇关于将 NWConnection 用于长时间运行的 TCP 套接字的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆