iOS 14上的UDP侦听器

汤姆坦克

我有一个关于如何在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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章