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)
}
}
}
}