0

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

  • 视图控制器类
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()
    }
}
  • UDP网络类
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()

        })
    }

}

苹果文档说:

receiveMessage(completion:)
为完整消息安排单个接收完成处理程序

完成
接收完成仅调用一次以进行接收调用。

  • 我的问题是:
    1. 我们如何打电话接收
    2. 假设receiveMessage(completion:)方法接收的调用,并且在接收到完成消息之后调用完成本身,如果它没有被调用,可能会出现什么问题?

可以在此处找到有关我的用例的相关代码和更多详细信息:
Swift: Receiving UDP packet from server on serial port monitor but not in ios app

有了这些假设:

  • 我们在发送数据的同一连接上调用接收
  • UDP 是用于连接的方法
  • 测试服务器是否正确交换端口,这意味着它响应数据发送到的相同 IP、端口
  • 我的设置:
    13" MacBookPro Early 2015 with MacOS Catalina 10.15
    Xcode Version 11.0 (11A420a)
    Swift 5.1
    target iOS 12+

这是 Wire Shark 的结果: 在此处输入图像描述

4

0 回答 0