NWListener, использующий параметр .udp, иногда вызывает странные журналы - PullRequest
2 голосов
/ 17 июня 2020

У меня есть простой класс UDPServer, который извлекает некоторые данные, и я могу установить, какой размер каждого пакета мне нужен. Когда я устанавливаю packetSize = 1024 (это свойство установлено в Windows настольном приложении), все работает нормально, но когда больше, например 2048, у меня появляются странные журналы, например:

[] udp_validate_cksum_internal [C6: 1] UDP неверная контрольная сумма IPv4-UDP без выгрузки 0xf3ff ulen 1506

[] nw_protocol_ipv4_get_input_frames_block_invoke [C6: 2] Удаление неиспользуемого дополнительного фрагмента IPv4

Устройства: iPhone 11, 11 Pro с iOS 13 - появляются логи

На симуляторах: iOS 12 и 13 - логов нет

Мой UDPServer:

final class UDPServer {
        
    var frameReceivedHandler: ((Data) -> Void)?
    
    private let listener: NWListener
    private let queue: DispatchQueue
    private var connection: NWConnection? {
        didSet { establishNewConnection(connection) }
    }
    
    deinit {
        stopListening()
    }
    
    init(port: UInt16) {
        self.queue = DispatchQueue(label: "UDP Server Queue")
        self.listener = try! NWListener(using: .udp,
                                        on: NWEndpoint.Port(integerLiteral: port))
    }
    
    // MARK: Public API
    
    func startListening() {
        listener.newConnectionHandler = { [weak self] newConnection in
            guard let self = self else { return }
            self.connection = newConnection
        }
        listener.start(queue: queue)
    }
    
    func stopListening() {
        listener.cancel()
        connection?.cancel()
    }
    
    // MARK: Private API
    
    private func establishNewConnection(_ newConnection: NWConnection?) {
        debugPrint("? New connection: \(String(describing: newConnection?.endpoint)) establish")
        newConnection?.stateUpdateHandler = { [weak self] connectionState in
            guard let self = self else { return }
            switch connectionState {
            case .ready:
                debugPrint("Connection: ✅ ready to receive")
                self.receive(on: newConnection)
            case .failed(let error): debugPrint("❌ Connection: failed: \(error)")
            case .cancelled: debugPrint("❌ Connection: cancelled")
            default: break
            }
        }
        newConnection?.start(queue: .main)
    }
    
    private func receive(on connection: NWConnection?) {
        connection?.receiveMessage { [weak self] content, context, isCompleted, error in
            guard let self = self else { return }
            if let frame = content {
                self.frameReceivedHandler?(frame)
            }
            self.receive(on: connection)
        }
    }
    
}

Мой пример использования:

udpVideoServer = UDPServer(port: /*port*/)
udpVideoServer.frameReceivedHandler = { [weak self] data in
    guard let self = self else { return }
    ...
}
udpVideoServer.startListening()

Я не нашел никакой полезной информации или объяснений по Inte rnet

Спасибо!

...