How to receive UDP Multicast and Unicast with Network Framework of iOS

864 Views Asked by At

I've been developing Smart House apps that require UDP communication of both Unicast and Multicast on iOS with Swift using CocoaAsyncSocket. I'd like to use Network Framework instead of CocoaAsyncSocket.

I made a following trial program of receiving UDP at 3610 port with both Unicast and Multicast at "224.0.23.0".

With this program, I'm having a problem to receive both Multicast and Unicast. This program can handle receiving Multicast, but not Unicast. When I comment out "receiveMulticast()" in the init(), this program can handle receiving Unicast. I need to handle receving both Multicast and Unicast at 3610 port.

Is there any advice?

=======================================

import Foundation
import Network

class Controller: ObservableObject {
  @Published var rxContents = String()
  @Published var rxFrom = String()
  
  init() {
    receiveMulticast()
    receiveUnicast()
  }
  
  func receiveUnicast() {
    guard let listener = try? NWListener(using: .udp, on: 3610)
    else { fatalError() }
    listener.newConnectionHandler = { (newConnection) in
      print("connection OK")
      newConnection.start(queue: .main)
      self.receive(on: newConnection)
    }
    listener.stateUpdateHandler = { (newState) in
      print("listener entered state \(String(describing: newState))")
    }
    listener.start(queue: .main)
  }

  func receiveMulticast() {
    guard let multicast = try? NWMulticastGroup(for: [ .hostPort(host: "224.0.23.0", port: 3610) ], disableUnicast: false)
    else { fatalError() }
    let group = NWConnectionGroup(with: multicast, using: .udp)
    group.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: true) { (message, content, isComplete) in
      print("Received message from \(String(describing: message.remoteEndpoint))")
      if let content = content, let message = String(data: content, encoding: .utf8) {
        print("Received Message: \(message)")
      }
    }
    group.stateUpdateHandler = { (newState) in
      print("Group entered state \(String(describing: newState))")
    }
    group.start(queue: .main)
  }
  
  private func receive(on connection: NWConnection) {
    connection.receiveMessage { (data: Data?, contentContext: NWConnection.ContentContext?, aBool: Bool, error: NWError?) in
      self.rxFrom = String(describing: connection.endpoint)
      print("Received message from \(self.rxFrom))")
      print(data ?? "data is null")
      if let data = data{
        self.rxContents = String(format: "%@", data as CVarArg)
        print("Received Message(unicast): \(self.rxContents)")
      }
      if let error = error {
        print(error)
      } else {
        self.receive(on: connection)
      }
    }
  }
}
0

There are 0 best solutions below