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 theNWConnection
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
iOS Swift Flood Fill Algorithm
Save Video to a Custom Album Using Photos Framework in iOS
How to Access Property or Method from a Variable
Scene Kit Memory Management Using Swift
Cgaffinetransformmakerotation with Negative M_Pi
Format Currency in Textfield in Swift on Input
Get Light or Dark Variant of a Color Declared in Assets
Uitextview - Adjust Size Based on the Content in Swiftui
Convert Nsdate to String with a Specific Timezone in Swift
Cannot Invoke 'Decode' with an Argument List of Type '(T, From: Data)'
How to Turn Off Core Data Write-Ahead Logging in Swift Using Options Dictionary
How to Make Uiscrollview Zoom in Only One Direction When Using Auto Layout
iOS Firebase Database Get Key of Value