So this is a bit of a weird one for me. I'm wanting to move my internal applications from CocoaAsync over the Network framework.
Communications is simple UDP and followed some of the advice from the forum as well as one of the WWDC videos talking about setting up NWConnection and NWListener.
I've created the classes and made a quick UI that sets up a sender and listener, with a couple of buttons that send two different UDP commands to my device.
Watching wire shark I see the data go out and the expected return message in WireShark, however, I only see the data come into the application from one type of message and not the other.
As you can see from the image above there are 4 packets (two sent, two received) but the program only seems to want to receive one return packet and not the other.
I double-checked and made sure that I can accept multiple receive messages and even tried sending from my iPad with its own message, and the message I was expecting the get from the other device. All seemed fine. I then checked the messaging in PacketSender and everything comes and goes as expected with messages.
This leads me back to a probable issue with how I'm implimenting the framework. Have I overlooked a parameter somewhere?
Sender Class
class UDPSender {
var connection:NWConnection
var connectionParams:NWParameters = .udp
init() {
connectionParams.allowLocalEndpointReuse = true
connectionParams.requiredLocalEndpoint = NWEndpoint.hostPort(host: "10.0.1.122", port: 2353)
connection = NWConnection(host: "10.0.1.161", port: 22202, using: connectionParams)
connection.stateUpdateHandler = {(newState) in
switch newState {
case .ready:
print("comms ready")
case .failed(let error):
print(error)
default:
break
}
}
connection.start(queue: DispatchQueue(label: "UDPSender"))
}
func send(message:Data) {
connection.send(content: message, completion: .contentProcessed({ (error) in
if let error = error {
print("Send error: \(error)")
} else {
print("Message Sent: \(message)")
}
}))
}
}
Listener Class
class UDPListener {
var listener:NWListener
var listenerParams:NWParameters = .udp
init(onPort port:NWEndpoint.Port) {
listenerParams.allowLocalEndpointReuse = true
listenerParams.acceptLocalOnly = false
listener = try! NWListener(using: listenerParams, on: port)
listener.stateUpdateHandler = {(newState) in
switch newState {
case .ready:
print("listener ready")
case .failed(let error):
print(error)
default:
break
}
}
listener.newConnectionHandler = {[weak self] (newConnection) in
if let strongSelf = self {
newConnection.start(queue: .main)
strongSelf.receive(on: newConnection)
}
}
listener.start(queue: DispatchQueue(label: "Listener"))
}
func receive(on connection:NWConnection) {
connection.receiveMessage { (content, context, isComplete, error) in
print(isComplete)
if error != nil {
print("Listener Error: \(String(describing:error))")
}
// if let package = content {
let str = String(decoding: content!, as: UTF8.self)
print("\(connection.endpoint) :: \(str)")
// }
if error == nil {
self.receive(on: connection)
}
}
}
}
ContentView
struct ContentView: View {
let listener = UDPListener(onPort:2353)
let comms = UDPSender()
var body: some View {
HStack {
Text("Press here")
Button(action: {
comms.send(message:"!nwd0#".data(using: .utf8)!)
}, label: {
Text("Send NWD")
})
Button(action: {
comms.send(message: "!nsd10.0.1.122:2353:\"From Button Press\"#".data(using: .utf8)!)
}, label: {
Text("Send NSD")
})
}.padding(10)
}
}