How to Work with Udp Sockets in iOS, Swift

How to work with UDP sockets in iOS, swift?

This solution work for me! Thanks @Paulw11

Swift 4, XCode 10.1, iOS 12.0

Simple connect to the public UDP server (This is NOT optimal version but works):

import UIKit
import Network

class ViewController: UIViewController {

var connection: NWConnection?
var hostUDP: NWEndpoint.Host = "iperf.volia.net"
var portUDP: NWEndpoint.Port = 5201

override func viewDidLoad() {
super.viewDidLoad()

// Hack to wait until everything is set up
var x = 0
while(x<1000000000) {
x+=1
}
connectToUDP(hostUDP,portUDP)
}

func connectToUDP(_ hostUDP: NWEndpoint.Host, _ portUDP: NWEndpoint.Port) {
// Transmited message:
let messageToUDP = "Test message"

self.connection = NWConnection(host: hostUDP, port: portUDP, using: .udp)

self.connection?.stateUpdateHandler = { (newState) in
print("This is stateUpdateHandler:")
switch (newState) {
case .ready:
print("State: Ready\n")
self.sendUDP(messageToUDP)
self.receiveUDP()
case .setup:
print("State: Setup\n")
case .cancelled:
print("State: Cancelled\n")
case .preparing:
print("State: Preparing\n")
default:
print("ERROR! State not defined!\n")
}
}

self.connection?.start(queue: .global())
}

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! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
}
})))
}

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! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
}
})))
}

func receiveUDP() {
self.connection?.receiveMessage { (data, context, isComplete, error) in
if (isComplete) {
print("Receive is complete")
if (data != nil) {
let backToString = String(decoding: data!, as: UTF8.self)
print("Received message: \(backToString)")
} else {
print("Data == nil")
}
}
}
}
}

Swift and UDP socket packet send twice

For everyone is interested, this issue is caused by the network. At home I've a Vodafone network, with their router (Vodafone Station Revolution). The Vodafone Station Revolution generate Wi-Fi @ 2,4GHz and Wi-Fi @ 5GHz. When I try to send an UDP packet on this network this packet will posted twice one for the 2,4GHz and one for the 5GHz network. So to solve my issue I disabled the 5GHz network and all work fine. It is not a code problem, indeed it's a network problem.
I hope my experience will be useful for other person who need the send UDP packet on Vodafone network.
By the way thank you for help.

UDP Listener on iOS 14

I was able to explore this some more and got some help via the apple developer forums, posting an answer here as well for those who are interested.

I ended up using an NWListener to listen for UDP packets, then set up an NWConnection once once I'd received something. I use this NWConnection to read data from the UDP broadcast.

From Quinn "The Eskimo:"

Listening for UDP broadcasts via an NWListener and then using the NWConnection objects it vends (via the new connection handler) to communicate over unicast with the broadcast’s sender is an expected use case.

I encourage anyone reading this to check out our discussion on the Apple Developer Forum as well.

Here is my implementation:

  var udpListener: NWListener?
var udpConnection: NWConnection?
var backgroundQueueUdpListener = DispatchQueue.main

func findUDP() {
let params = NWParameters.udp
udpListener = try? NWListener(using: params, on: 15000)

udpListener?.service = NWListener.Service.init(type: "_appname._udp")

self.udpListener?.stateUpdateHandler = { update in
print("update")
print(update)
switch update {
case .failed:
print("failed")
default:
print("default update")
}
}
self.udpListener?.newConnectionHandler = { connection in
print("connection")
print(connection)
self.createConnection(connection: connection)
self.udpListener?.cancel()
}
udpListener?.start(queue: self.backgroundQueueUdpListener)
}

func createConnection(connection: NWConnection) {
self.udpConnection = connection
self.udpConnection?.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
print("ready")
self.send()
self.receive()
case .setup:
print("setup")
case .cancelled:
print("cancelled")
case .preparing:
print("Preparing")
default:
print("waiting or failed")
}
}
self.udpConnection?.start(queue: .global())
}

func endConnection() {
self.udpConnection?.cancel()
}

Swift: Receive UDP with GCDAsyncUdpSocket

I finally got it to work with this socket setup:

func setupConnection(){
var error : NSError?
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
socket.bindToPort(PORT, error: &error)
socket.connectToHost(SERVER_IP, onPort: PORT, error: &error)
socket.beginReceiving(&error)
send("ping")
}

func send(message:String){
let data = message.dataUsingEncoding(NSUTF8StringEncoding)
socket.sendData(data, withTimeout: 2, tag: 0)
}


Related Topics



Leave a reply



Submit