Я хотел бы получать некоторые данные через UDP в бесконечном количестве l oop, пока пользователь не отменит получение данных. Я создал NWListener и настроил его. Он получает данные, как и ожидалось. Однако, когда я вызываю .cancel () на моем NWListener , он меняет состояние на .cancelled , но после этого у меня нет шансов снова запустить процесс прослушивания. Это как-то блокирует порт. Я мог бы перезапустить его на другой порт, но это не то, что я хочу сделать. На том же порту это заканчивается в этом сообщении об ошибке:
2020-02-20 23:00:28.957501+0100 networking[10942:7110395] [] nw_path_evaluator_evaluate NECP_CLIENT_ACTION_ADD error [48: Address already in use]
2020-02-20 23:00:28.957642+0100 networking[10942:7110395] [] nw_path_create_evaluator_for_listener nw_path_evaluator_evaluate failed
2020-02-20 23:00:28.957735+0100 networking[10942:7110395] [] nw_listener_start_locked [L2] nw_path_create_evaluator_for_listener failed
?????? NWListener Handler called
Listener: Failed POSIXErrorCode: Address already in use
Я создал специальный проект примера в XCode, чтобы решить проблему как можно лучше и гарантировать, что это не имеет никакого отношения к остальной части мой актуальный проект. Это ViewController, который я создал, чтобы показать проблему, я просто подключил две кнопки для запуска / остановки прослушивания 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: [])
override func viewDidLoad() {
super.viewDidLoad()
myOnButton(self)
}
@IBAction func myOnButton(_ sender: Any) {
do {
self.udpListener = try NWListener(using: .udp, on: 55555)
self.udpListener?.stateUpdateHandler = { (listenerState) in
print("?????? NWListener Handler called")
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")
default:
break;
}
}
self.udpListener?.start(queue: backgroundQueueUdpListener)
self.udpListener?.newConnectionHandler = { (incomingUdpConnection) in
print("??? NWConnection Handler called ")
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.processData(incomingUdpConnection)
case .failed(let error):
print("Connection: ? failed: \(error)")
case .cancelled:
print("Connection: ? cancelled")
default:
break
}
}
incomingUdpConnection.start(queue: self.backgroundQueueUdpConnection)
}
} catch {
print("??? CATCH")
}
}
@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)")
}
}
//print ("context = \(context)")
print ("isComplete = \(isComplete)")
//print ("error = \(error)")
self.processData(incomingUdpConnection)
})
}
}
Я надеюсь, что кто-то может мне помочь, я потратил сейчас несколько часов, чтобы решить эту проблему, но пока безуспешно.
Чтобы проверить входящие сообщения через UDP, я использовал этот сценарий оболочки:
#!/bin/zsh
while :
do
echo "1234" | nc -cu -w 0 192.168.2.106 55555
sleep 1
echo "567890" | nc -cu -w 0 192.168.2.106 55555
sleep 1
done