NWNetworking / NWListener how to correctly receive UDP broadcast messages?

I have the following code running fine when receiving direct messages via UDP:


import UIKit
import Network

class ViewController: UIViewController {

    var udpListener:NWListener?
    var backgroundQueueUdpListener   = DispatchQueue(label: "udp-lis.bg.queue", attributes: [])
    var backgroundQueueUdpConnection = DispatchQueue(label: "udp-con.bg.queue", attributes: [])
            
    var connections = [NWConnection]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        myOnButton(self)
    }
    
    @IBAction func myOnButton(_ sender: Any) {
        
        guard self.udpListener == nil else {
            print(" ???? Already listening. Not starting again")
            return
        }
        
        do {
            self.udpListener = try NWListener(using: .udp, on: 2000)
            self.udpListener?.stateUpdateHandler = { (listenerState) in
                
                switch listenerState {
                case .setup:
                    print("Listener: Setup")
                case .waiting(let error):
                    print("Listener: Waiting (error)")
                case .ready:
                    print("Listener: Ready and listens on port: (self.udpListener?.port?.debugDescription ?? "-")")
                case .failed(let error):
                    print("Listener: Failed (error)")
                case .cancelled:
                    print("Listener: Cancelled by myOffButton")
                    for connection in self.connections {
                        connection.cancel()
                    }
                    self.udpListener = nil
                default:
                    break;
                }
            }
            
            self.udpListener?.start(queue: backgroundQueueUdpListener)
            self.udpListener?.newConnectionHandler = { (incomingUdpConnection) in

                print ("???? New connection (incomingUdpConnection.debugDescription)")
                
                incomingUdpConnection.stateUpdateHandler = { (udpConnectionState) in
                    switch udpConnectionState {
                    case .setup:
                        print("Connection: setup")
                    case .waiting(let error):
                        print("Connection: waiting: (error)")
                    case .ready:
                        print("Connection: ready")
                        self.connections.append(incomingUdpConnection)
                        self.processData(incomingUdpConnection)
                    case .failed(let error):
                        print("Connection: failed: (error)")
                        self.connections.removeAll(where: {incomingUdpConnection === $0})
                    case .cancelled:
                        print("Connection: cancelled")
                        self.connections.removeAll(where: {incomingUdpConnection === $0})
                    default:
                        break
                    }
                }

                incomingUdpConnection.start(queue: self.backgroundQueueUdpConnection)
            }
            
        } catch {
            print("????")
        }
        
    }
    @IBAction func myOffButton(_ sender: Any) {
        udpListener?.cancel()
    }
  
    func processData(_ incomingUdpConnection :NWConnection) {
        
        incomingUdpConnection.receiveMessage(completion: {(data, context, isComplete, error) in
            
            if let data = data, !data.isEmpty {
                if let string = String(data: data, encoding: .ascii) {
                    print ("DATA       = (string)")
                }
            }

            if error == nil {
                self.processData(incomingUdpConnection)
            }
        })
        
    }
   
}


Sending endless UDP packages directly to the device like this:

echo -n "Testdata" | socat - udp-datagram:192.168.2.126:2000,broadcast,sourceport=2000

works as expected, and all messages arrive:

Listener: Waiting POSIXErrorCode: Network is down
Listener: Ready and listens on port: 2000
???? New connection [C1 192.168.2.134:2000 udp, local: 192.168.2.126:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, scoped, ipv4, ipv6, dns]
Connection: ready
DATA       = Testdata
DATA       = Testdata
DATA       = Testdata
DATA       = Testdata
...

But trying the same with broadcast messages

echo -n "Testat" | socat - udp-datagram:255.255.255.255:2000,broadcast,sourceport=2000

results in only receiving the first message, and a new connection with each received UDP package.


Listener: Waiting POSIXErrorCode: Network is down
Listener: Ready and listens on port: 2000
???? New connection [C1 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
Connection: ready
DATA       = Testdata
2020-06-28 14:22:03.668116+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot 77926755-A281-4AFD-9649-92FBD1A21FA6
???? New connection [C2 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
2020-06-28 14:22:04.384443+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot 7EAC98FA-F665-43C1-9B15-B68B74A56BBC
???? New connection [C3 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
2020-06-28 14:22:05.096808+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot AA3EE3BA-D891-4D07-87AF-0CB0A9382CDF
???? New connection [C4 192.168.2.134:2000 udp, local: 0.0.0.0:2000, indefinite, server, path satisfied (Path is satisfied), interface: en0, ipv4, ipv6, dns]
2020-06-28 14:22:05.714651+0200 networking[25440:13489733] [] nw_channel_reclassify_input reclassify failed, could not find client for slot ED108E8B-E9BC-43C3-8AA7-B4BD0515EB54

Workaround would be to .cancel the connection after each received package, but I doubt this is the way how this was intended to be used to receive UDP broadcast messages. So what is the correct approach to receive UDP broadcast packages in an endless loop?

1

Ok, I got sort of an answer.

I had the same basic issue in Objective-C. I took the step of cancelling the connection in the handler, which sort of works, but you end up with data loss – about 30% in my experience – as the stream fails to pick up broadcast data.

However, I did get feedback from dts, which is basically this – Networking Library is not designed for receiving broadcast UDP.

I’ve reverted to BSD sockets.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật