[英]Swift UDP Connection Issue
protocol UDPListener {
func handleResponse(_ client: UDPConnection, data: Data)
}
class UDPConnection{
var connection: NWConnection?
var listner: NWListener?
var delegate: UDPListener?
let parameters = NWParameters.udp
// for connect with device
func connect(withHost: NWEndpoint.Host, port: NWEndpoint.Port) {
parameters.allowLocalEndpointReuse = true
self.connection = NWConnection(host: withHost, port: port, using: parameters)
self.connection?.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
print("connection ready")
case .setup:
print("connectionsetup")
case .cancelled:
print("connectioncancelled")
case .preparing:
print("connection Preparing")
default:
print("connection waiting or failed")
}
}
self.connection?.start(queue: .global())
}
// for sending UDP string
func sendUDP(_ content: String) {
let contentToSendUDP = content.data(using: String.Encoding.utf8)
self.connection?.send(content: contentToSendUDP, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
if (NWError == nil) {
print("Data was sent to UDP")
} else {
print("ERROR SEND! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
}
})))
}
//for sending UDP data
func sendUDP(_ content: Data) {
self.connection?.send(content: content, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
if (NWError == nil) {
print("Data was sent to UDP")
} else {
print("ERROR Send! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
}
})))
}
//////////////// UDP LISTNER /////////////////////
func listenUDP(port: NWEndpoint.Port) {
do {
parameters.allowLocalEndpointReuse = true
self.listner = try NWListener(using: parameters, on: port)
self.listner?.stateUpdateHandler = {(newState) in
switch newState {
case .ready:
print("Listner ready")
case .failed:
print("Listner failed")
case .cancelled:
print("Listner cancelled")
default:
break
}
}
self.listner?.newConnectionHandler = {(newConnection) in
newConnection.stateUpdateHandler = {newState in
switch newState {
case .ready:
print("new connection establish")
self.receive(on: newConnection)
case .failed:
print("new connection failed")
case .cancelled:
print("new connection cancelled")
default:
break
}
}
newConnection.start(queue: DispatchQueue(label: "new client"))
}
} catch {
print("unable to create listener")
}
self.listner?.start(queue: .global())
}
func receive(on connection: NWConnection) {
connection.receiveMessage { (data, context, isComplete, error) in
if !isComplete {
print("Not Complete")
}
if let error = error {
print("Error in REceive: - ",error)
return
}
if let data = data, !data.isEmpty {
// let backToString = String(decoding: data, as: UTF8.self)
// print("Received Data: ",backToString)
guard self.delegate != nil else {
print("Error Receive: UDPClient response handler is nil")
return
}
print("Data receive in UDPConenction;")
self.delegate?.handleResponse(self, data: data)
}
}
}
}
在这里,我附上了我的 UDP 文件,其中包含 UDP 的连接和侦听器。
当我第一次发送一些数据时,它会发送数据并接收数据。
但是当我再次发送数据时,数据将被发送,但我不会第二次及以后获取数据。 Listner 不再列出。 数据将被发送,但侦听器未在侦听。
如果我关闭应用程序并再次运行它,也会出现同样的问题。 第一次加载数据(侦听器侦听数据)但第二次侦听器不起作用。
我的代码有什么问题? 我尝试了很多,但没有解决问题。 请任何可以解决我的问题的人都会非常感谢我。
先感谢您。
如果您在此处查看文档,则在您的函数receive
您正在使用NWConnection.receiveMessage
:
https://developer.apple.com/documentation/network/nwconnection/3020638-receivemessage
您会看到它调度了一个接收完成处理程序。 这意味着你必须做一些事情才能再次触发它。 我通常做的是有一个功能,如:
private func setupReceive() {
connection.receive(minimumIncompleteLength: 1, maximumLength: MTU) { (data, _, isComplete, error) in
if let data = data, !data.isEmpty {
let message = String(data: data, encoding: .utf8)
print("connection \(self.id) did receive, data: \(data as NSData) string: \(message ?? "-")")
self.send(data: data)
}
if isComplete {
self.connectionDidEnd()
} else if let error = error {
self.connectionDidFail(error: error)
} else {
self.setupReceive() // HERE I SET THE RECEIVE AGAIN
}
}
}
这样,在处理读取之后,您最终会设置另一个单个接收完成处理程序。
如果您想查看完整示例,可以在此处查看我关于使用Network.framework
文章:
https://rderik.com/blog/building-a-server-client-aplication-using-apple-s-network-framework/
该示例使用 TCP 而不是 UDP,但它应该给出一个大致的概念。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.