Swift:在NWConnection类中何时调用receiveMessage(completion:)

时间:2019-10-21 10:41:24

标签: ios xcode udp swift5.1

我想通过UDP模块与wifi模块作为服务器,而与iOS作为客户端并发送/接收数据(显然)。首先,我想使用Sockets,但是后来我意识到Apple引入了Network框架;因此,出于我的目的,我使用了NWConnection框架中的类Network,并且我成功地将数据发送到设备,但无法接收到响应(当我监视设备时,我肯定存在该响应) / O数据包通过串行端口监视器)。这是代码的测试版本,其中我使用netcat作为服务器来测试连接:

  • ViewController类
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类
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: Receiving UDP packets from server on serial port monitor but not in ios app

基于这些假设:

  
      
  • 我们打电话来接收与我们向其发送数据的同一连接
  •   
  • 使用UDP进行连接
  •   
  • 经过测试,服务器可以正确交换端口,这意味着它可以在将数据发送到的同一IP端口上进行响应
  •   
  • 我的设置:
    具有MacOS Catalina 10.15的13英寸MacBookPro 2015年初
    Xcode版本11.0(11A420a)
    Swift 5.1
    目标iOS 12以上版本

这是Wire Shark的结果: enter image description here

0 个答案:

没有答案