我想与作为服务器的 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:)
为完整消息安排单个接收完成处理程序完成:
接收完成仅调用一次以进行接收调用。
- 我的问题是:
- 我们如何打电话接收?
- 假设
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+