【发布时间】:2019-03-04 04:12:10
【问题描述】:
我整天都在与 NWConnection 斗争,以便在长时间运行的 TCP 套接字上接收数据。由于缺乏文档,在对自己造成以下错误后,我终于让它工作了:
- 数据不完整(由于只调用receive一次)
- 无序获取 TCP 数据(由于从计时器“轮询”接收...导致多个同时关闭等待获取数据)。
- 遭受无限循环(由于在接收后重新启动接收而没有检查“isComplete”布尔值——一旦套接字从另一端终止,这是....糟糕......非常糟糕)。
我所学的总结:
- 一旦您处于 .ready 状态,您就可以调用 receive...一次且仅一次
- 收到一些数据后,您可以再次调用 receive...但前提是您仍处于 .ready 状态并且 isComplete 为 false。
这是我的代码。我认为这是对的。但如果有错误请告诉我:
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()
}
}
}
【问题讨论】:
-
我希望今天早上能找到这篇文章。我正在努力解决如果我使用 connection.send 发送多个数据位然后连接接收将数据组合在一起的问题。我应该将其视为仅在网络上发生的事情,还是应该限制我的发送,还是应该以不同的方式发送?
-
我无法回答这个问题,但这听起来是一个很好的问题,尤其是在您包含代码的情况下。我希望看到更多 NWconnection 代码示例。
-
所以,这表明我有点以错误的方式使用它(AFAIK)。我把连接看作是你打开的管道,然后不断地把东西放进去。当我将其视为 NWConnection 是用于发送单个事物并在该单个事物之后关闭时,一切都开始正常工作。
-
如果要多次连接可以处理
newConnectionHandler,在服务器上重启NWListener和NWConnection。 -
不需要定时器。您应该处理
NWConnection.receiveMessage来获取消息并调用receiveNextMessage() 来获取下一个。
标签: swift networking