Я хочу иметь UDP-соединение с модулем Wi-Fi в качестве сервера и iOS в качестве клиента и отправлять / получать данные (очевидно). Сначала я хотел использовать Sockets, но потом понял, что Apple представила Network
Framework;Поэтому я использовал NWConnection
, который является классом от Network
Framework для моей цели, и я успешно отправил данные на устройство, но не смог получить ответ (который, я уверен, существует, так как я отслеживаю пакеты ввода-вывода устройства черезмонитор последовательного порта). Вот тестовая версия кода, где я использую 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()
}
}
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:)
Планирует обработчик завершения одного приемадля полного сообщения
завершение :
Завершение приема вызывается ровно один раз для получения вызова.
- Мой вопрос:
- Как мы можем позвонить, чтобы получить ?
- Предполагая, что метод
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: