作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当通过 UDP 接收直接消息时,我可以正常运行以下代码:
import UIKit
import Network
class ViewController: UIViewController {
var udpListener:NWListener?
var backgroundQueueUdpListener = DispatchQueue(label: "udp-lis.bg.queue", attributes: [])
var backgroundQueueUdpConnection = DispatchQueue(label: "udp-con.bg.queue", attributes: [])
var connections = [NWConnection]()
override func viewDidLoad() {
super.viewDidLoad()
myOnButton(self)
}
@IBAction func myOnButton(_ sender: Any) {
guard self.udpListener == nil else {
print(" 🧨 Already listening. Not starting again")
return
}
do {
self.udpListener = try NWListener(using: .udp, on: 2000)
self.udpListener?.stateUpdateHandler = { (listenerState) in
switch listenerState {
case .setup:
print("Listener: Setup")
case .waiting(let error):
print("Listener: Waiting \(error)")
case .ready:
print("Listener: Ready and listens on port: \(self.udpListener?.port?.debugDescription ?? "-")")
case .failed(let error):
print("Listener: Failed \(error)")
case .cancelled:
print("Listener: Cancelled by myOffButton")
for connection in self.connections {
connection.cancel()
}
self.udpListener = nil
default:
break;
}
}
self.udpListener?.start(queue: backgroundQueueUdpListener)
self.udpListener?.newConnectionHandler = { (incomingUdpConnection) in
print ("💁 New connection \(incomingUdpConnection.debugDescription)")
incomingUdpConnection.stateUpdateHandler = { (udpConnectionState) in
switch udpConnectionState {
case .setup:
print("Connection: setup")
case .waiting(let error):
print("Connection: waiting: \(error)")
case .ready:
print("Connection: ready")
self.connections.append(incomingUdpConnection)
self.processData(incomingUdpConnection)
case .failed(let error):
print("Connection: failed: \(error)")
self.connections.removeAll(where: {incomingUdpConnection === $0})
case .cancelled:
print("Connection: cancelled")
self.connections.removeAll(where: {incomingUdpConnection === $0})
default:
break
}
}
incomingUdpConnection.start(queue: self.backgroundQueueUdpConnection)
}
} catch {
print("🧨")
}
}
@IBAction func myOffButton(_ sender: Any) {
udpListener?.cancel()
}
func processData(_ incomingUdpConnection :NWConnection) {
incomingUdpConnection.receiveMessage(completion: {(data, context, isComplete, error) in
if let data = data, !data.isEmpty {
if let string = String(data: data, encoding: .ascii) {
print ("DATA = \(string)")
}
}
if error == nil {
self.processData(incomingUdpConnection)
}
})
}
}
像这样直接向设备发送无穷无尽的 UDP 包:
echo -n "Testdata" | socat - udp-datagram:192.168.2.126:2000,broadcast,sourceport=2000
按预期工作,所有消息都到达:
Listener: Waiting POSIXErrorCode: Network is down
Listener: Ready and listens on port: 2000
💁 New connection [C1 192.168.2.134:2000 udp, local: 192.168.2.126:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, scoped, ipv4, ipv6, dns]
Connection: ready
DATA = Testdata
DATA = Testdata
DATA = Testdata
DATA = Testdata
...
但尝试对广播消息进行同样的操作
echo -n "Testat" | socat - udp-datagram:255.255.255.255:2000,broadcast,sourceport=2000
导致仅接收第一条消息,并与每个接收到的 UDP 数据包建立新连接。
Listener: Waiting POSIXErrorCode: Network is down
Listener: Ready and listens on port: 2000
💁 New connection [C1 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
Connection: ready
DATA = Testdata
2020-06-28 14:22:03.668116+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot 77926755-A281-4AFD-9649-92FBD1A21FA6
💁 New connection [C2 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
2020-06-28 14:22:04.384443+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot 7EAC98FA-F665-43C1-9B15-B68B74A56BBC
💁 New connection [C3 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
2020-06-28 14:22:05.096808+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot AA3EE3BA-D891-4D07-87AF-0CB0A9382CDF
💁 New connection [C4 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
2020-06-28 14:22:05.714651+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot ED108E8B-E9BC-43C3-8AA7-B4BD0515EB54
解决方法是在每次收到数据包后取消连接,但我怀疑这是用于接收 UDP 广播消息的方式。那么死循环接收UDP广播包的正确做法是什么?
最佳答案
好的,我得到了某种答案。
我在 Objective-C 中遇到了同样的基本问题。我采取了取消处理程序中的连接的步骤,这种方法可行,但您最终会丢失数据 - 根据我的经验,大约 30% - 因为流无法获取广播数据。
不过,我确实从 dts 那里得到了反馈,基本上是这样的——网络库不是为接收广播 UDP 而设计的。
我已经恢复到 BSD 套接字。
关于ios - NWNetworking/NWListener如何正确接收UDP广播报文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62622612/
我有一个应用程序,我应该有一个 websocket 只在应用程序处于前台时才监听我已经进入生命周期通知并调用 start() 并相应地停止。该应用程序可以正常工作,直到应用程序回到前台,此时我收到了许
我是一名优秀的程序员,十分优秀!