Swift: в классе NWConnection, когда вызывается метод receiveMessage (завершение :) - PullRequest
0 голосов
/ 21 октября 2019

Я хочу иметь UDP-соединение с модулем Wi-Fi в качестве сервера и iOS в качестве клиента и отправлять / получать данные (очевидно). Сначала я хотел использовать Sockets, но потом понял, что Apple представила Network Framework;Поэтому я использовал NWConnection, который является классом от Network Framework для моей цели, и я успешно отправил данные на устройство, но не смог получить ответ (который, я уверен, существует, так как я отслеживаю пакеты ввода-вывода устройства черезмонитор последовательного порта). Вот тестовая версия кода, где я использую netcat в качестве сервера для проверки соединения:

  • ViewController Class
import UIKit
import Network

class ViewController: UIViewController
{
    var network: UDPNetwork!

    override func viewDidLoad()
    {
        super.viewDidLoad()

    }

    @IBAction func button(_ sender: Any)
    {
        self.network = UDPNetwork(host: "192.168.200.4", port:"4210")!
        self.network.connect()
    }
}
  • UDPNetwork Class
import Foundation
import Network

class UDPNetwork {

    var hostUDP: NWEndpoint.Host
    var portUDP: NWEndpoint.Port

    private var connection: NWConnection?

    private var queue = DispatchQueue(label: "NetworkQuue", qos: .utility)

    init?(host: String, port: String) {

        guard !host.isEmpty, let portUDP = NWEndpoint.Port(port) else {
            return nil
        }

        self.hostUDP = NWEndpoint.Host(host)
        self.portUDP = portUDP
    }


    func connect()
    {
        connection = NWConnection(host: hostUDP, port: portUDP, using: .udp)
        connection?.stateUpdateHandler =
            {
                (newState) in switch (newState)
                {
                case .ready:
                    //The connection is established and ready to send and recieve data.
                    print("ready")
                    self.sendPaket("Hello")
                    self.receive()
                case .setup:
                    //The connection has been initialized but not started
                    print("setup")
                case .cancelled:
                    //The connection has been cancelled
                    print("cancelled")
                case .preparing:
                    //The connection in the process of being established
                    print("Preparing")
                default:
                    //The connection has disconnected or encountered an error
                    print("waiting or failed")
                }
        }
        connection?.start(queue: self.queue)
    }

    func sendPaket(_ packet:String)
    {
        let packetData = packet.data(using: .utf8)
        self.connection?.send(content: packetData, completion: NWConnection.SendCompletion.contentProcessed(({ (error) in
            if let err = error {
                print("Sending error \(err)")
            } else {
                print("Sent successfully")
            }
        })))

    }

    func receive()
    {
        self.connection?.receiveMessage(completion:
            {
                (data, context, isComplete, error) in
                print("Got it")
                if let err = error {
                    print("Recieve error: \(err)")
                }

                if let rcvData = data,
                    let str = String(data:rcvData, encoding: .utf8) {
                    print("Received: \(str)")
                }

                self.receive()

        })
    }

}

Документация Apple гласит:

receiveMessage(completion:)
Планирует обработчик завершения одного приемадля полного сообщения

завершение :
Завершение приема вызывается ровно один раз для получения вызова.

  • Мой вопрос:
    1. Как мы можем позвонить, чтобы получить ?
    2. Предполагая, что метод receiveMessage(completion:) равен Позвоните, чтобы получить , а также после получения полного сообщения вызывает само завершение, Чтоможет быть проблема, если он не вызывается?

Связанный код и более подробную информацию о моем случае использования можно найти здесь:
Swift: ReceivingUDP-пакеты от сервера на мониторе последовательного порта, но не в приложении ios

С этими допущениями:

  • Мы вызываем для получения по тому же соединению, что мы отправляем данныена
  • UDP используется для подключения
  • Сервер проверен на правильную перестановку портов, то есть он отвечает на тот же IP-адрес, Порт, на который отправляются данные
  • Моя настройка:
    13 "MacBookPro, начало 2015 года, с MacOS Catalina 10.15
    Версия Xcode 11.0 (11A420a)
    Swift 5.1
    цель iOS 12+

И это результат Wire Shark: enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...