Here’s the code that drops a huge amount of datagrams. I have also tried with queue .main with the same results. Using NWConnection.receive or .receiveMessage makes no difference.
import Network
import SwiftUI
class udpCatcher: ObservableObject {
init() {
print("init started.")
var lastTime = Date() // used to know how much time it took between receiving datagrams, mostly for my use in combination with optional filtering for specific data that can be enabled by un-commenting some code below
var counter = 0 // used to add indentation to better follow the scrolling of the data
let printState = false // if false then only the data will print, if true then also the state of the listener and the connection
let listener = try! NWListener(using: .udp, on: 5000)
listener.newConnectionLimit = NWListener.InfiniteConnectionLimit
listener.stateUpdateHandler = { state in
if printState {print("listener state: \(listener.state)")}
}
listener.newConnectionHandler = { connection in
if printState {print("newConnectionHandler triggered: connection state: \(connection.state), listener state: \(listener.state)")}
connection.stateUpdateHandler = { newState in
switch newState {
case .ready:
if printState {print("Connection state: \(connection.state), listener state: \(listener.state)")}
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { (data, context, isComplete, error) in
if let data = data, !data.isEmpty {
var message = String(decoding: data, as: UTF8.self)
// if message.hasPrefix("$XXXX") { // for optional filtering of messages
counter += 1
if counter % 5 == 0 { // indentation every 5th line to better follow the scrolling
print("\(counter) Received data: \(message) \((Date().timeIntervalSince(lastTime)*100).rounded()/100)\"")
} else {
print("\(counter) Received data: \(message) \((Date().timeIntervalSince(lastTime)*100).rounded()/100)\"")
}
lastTime = Date()
// }
// Process the data here
}
if let error = error {
if printState {print("Connection error: \(error)")}
}
if isComplete {
connection.cancel()
if printState {print("Connection state: \(connection.state), listener state: \(listener.state)")}
}
}
case let .failed(error):
if printState {print("Connection failed with error \(error.localizedDescription), listener state: \(listener.state)")}
default:
if printState {print("Connection state: \(connection.state), listener state: \(listener.state)")}
}
}
connection.start(queue: .global(qos: .userInteractive))
}
listener.start(queue: .global(qos: .userInteractive))
}
}