我有一个关于如何在iOS 14上设置UDP侦听器的问题。我有一个过去使用过的UDP侦听器,但是更新到iOS 14后,它偶尔会起作用/根本无法工作。
它位于NSObject中,并在端口15000(无特定IP地址)上侦听本地网络上的UDP广播。它使用CocoaAsyncSocket库。当我致电时setUpSocket()
,不会触发本地网络权限,但该应用程序可以偶尔接收UDP数据包。
var socket: GCDAsyncUdpSocket?
var broadcastPort: UInt16 = 15000
var broadcastAddress: String = ""
var connectAddress = ""
var connectPort = 0
func setUpSocket() {
findUDP()
let socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
socket.setIPv4Enabled(true)
socket.setIPv6Enabled(false)
do {
try socket.bind(toPort: broadcastPort) /*15000*/
try socket.enableBroadcast(false)
try socket.beginReceiving()
} catch let error as NSError {
print("Issue with setting up listener \(error)")
}
}
/*Called when UDP packets are received.*/
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress: Data, withFilterContext filterContext: Any?) {
do {
let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
if (connected == false) {
if (jsonDictionary["Addresses"] != nil) {
if (jsonDictionary["Addresses"] is NSArray) {
let addresses = jsonDictionary["Addresses"] as! NSArray
for i in addresses {
let ipAddress:String = i as! String
if (ipAddress.range(of: "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$", options: .regularExpression) != nil) {
connectAddress = ipAddress
}
}
connectPort = jsonDictionary["Port"] as! Int
}
/*Sets up a TCP connection on the IP and Port provided in the UDP broadcast.*/
setupNetworkCommunication(ip: connectAddress, port: connectPort)
closeSocket()
}
}
} catch let error {
return print(error)
}
}
如何更新此版本以符合iOS 14?如果需要更新以使用Bonjour服务,如何在不指定地址的情况下在端口上侦听(而不必查找特定的Bonjour服务广播,因为我要查找的广播不使用Bonjour)。
快速打开和关闭Bonjour NWBrowser以触发网络权限,然后按原样使用我的代码是否可以接受?这似乎可行,但充其量似乎很hacky。
提前致谢。
我能够进行更多探索,并通过苹果开发者论坛获得了一些帮助,并在此处为有兴趣的人发布了答案。
我最终使用NWListener侦听UDP数据包,然后在收到某些信息后立即建立NWConnection。我使用此NWConnection从UDP广播中读取数据。
摘自奎因《爱斯基摩人》:
预期使用案例通过侦听UDP广播
NWListener
,然后使用NWConnection
它出售的对象(通过新的连接处理程序)通过单播与广播的发送方进行通信。
我鼓励阅读此书的任何人也可以在Apple Developer Forum上查看我们的讨论。
这是我的实现:
var udpListener: NWListener?
var udpConnection: NWConnection?
var backgroundQueueUdpListener = DispatchQueue.main
func findUDP() {
let params = NWParameters.udp
udpListener = try? NWListener(using: params, on: 15000)
udpListener?.service = NWListener.Service.init(type: "_appname._udp")
self.udpListener?.stateUpdateHandler = { update in
print("update")
print(update)
switch update {
case .failed:
print("failed")
default:
print("default update")
}
}
self.udpListener?.newConnectionHandler = { connection in
print("connection")
print(connection)
self.createConnection(connection: connection)
self.udpListener?.cancel()
}
udpListener?.start(queue: self.backgroundQueueUdpListener)
}
func createConnection(connection: NWConnection) {
self.udpConnection = connection
self.udpConnection?.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
print("ready")
self.send()
self.receive()
case .setup:
print("setup")
case .cancelled:
print("cancelled")
case .preparing:
print("Preparing")
default:
print("waiting or failed")
}
}
self.udpConnection?.start(queue: .global())
}
func endConnection() {
self.udpConnection?.cancel()
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句