0

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)
      }
    }
  }
}
  • You have set disableUnicast to false, so you perhaps you don't need separate multicast and unicast listeners? – Paulw11 Aug 26 '21 at 02:29
  • When I comment out receiveUnicast() in the init(), this program can handle receiving Multicast, but not Unicast. – Hiro Fujita Aug 26 '21 at 02:31

0 Answers0