How to work with UDP sockets in iOS, swift?
Solution 1
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")
}
}
}
}
}
Solution 2
You need to wait until your connection is in the ready
state before you try and send or receive any data. You will also need to hold a strong reference to your connection in a property to prevent it from being released as soon as the function exits.
var connection: NWConnection?
func someFunc() {
self.connection = NWConnection(host: "255.255.255.255", port: 9093, using: .udp)
self.connection?.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.connection?.start(queue: .global())
}
func send() {
self.connection?.send(content: "Test message".data(using: String.Encoding.utf8), completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
print(NWError)
})))
}
func receive() {
self.connection?.receiveMessage { (data, context, isComplete, error) in
print("Got it")
print(data)
}
}
SBlincov
Winner of international and Russian olympiads, contests and hackathons: Since my school days, I have become the winner of many International, Russian and regional hackathons, contests and olympiads in computer science, economics and programming. Skoltech Master's student: I am studying at the Skoltech University Master's program in Information Science and Technology. IoT track. Graduated from the Institute of Information Technologies, Mathematics and Mechanics of the Lobachevsky University (UNN) in the direction of "Software Engineering". Graduated from the program "Innovative Entrepreneurship" FPK UNN. iOS developer: I am developing mobile applications for the iOS operating system. I have experience as team and as independent developer. Developed mobile applications for banks, startups, UAV manufacturer, government, Russian and foreign customers. Technology entrepreneur: I take an active part in the development of my own projects: "meCare", "BeDance" and hardware and software complex for the development of communication skills of people with ASD. My personal web-site: SBlincov.ru
Updated on July 22, 2022Comments
-
SBlincov almost 2 years
I'm trying connect to local esp8266 UDP server. SwiftSocket haven't documentation. CocoaAsyncSocket doesn't work. How to connect and send data to udp server? What i should do?
I wrote sample UDP python server and tried connect to them via SwiftSocket and CocoaAsyncSocket. I'm don't get feedback from app. Server don't receive connections. For example- one of the most attempts:
var connection = NWConnection(host: "255.255.255.255", port: 9093, using: .udp) connection.stateUpdateHandler = { (newState) in switch (newState) { case .ready: print("ready") case .setup: print("setup") case .cancelled: print("cancelled") case .preparing: print("Preparing") default: print("waiting or failed") break } } connection.start(queue: .global()) connection.send(content: "Xyu".data(using: String.Encoding.utf8), completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in print(NWError) }))) connection.receiveMessage { (data, context, isComplete, error) in print("Got it") print(data) }
Can't connect to the server
-
SBlincov over 5 yearsThank you for answer! When i'm run this code on empty project (run someFunction() from viewDidLoad() ) i get this error:
-
SBlincov over 5 years2019-02-12 22:28:41.553015+0300 Nanopix Pilot[3891:189405] [] nw_socket_service_writes_block_invoke [C1:1] sendmsg(fd 5, 3 bytes) [13: Permission denied]
-
Paulw11 over 5 yearsYou are trying to send a broadcast packet; I am not sure if this is permitted. It would be better to send a packet to the specific host you are trying to communicate with
-
SBlincov over 5 yearsThank you so much! I successfully connected to public UDP server. Below i write final code
-
user3069232 over 4 yearsTrying to get this to work on swift 5.x iOS 13. Sends data no problem, but I cannot seem to get it to receive anything. I am trying to use a python script to send a simple message.
-
Flo over 4 yearsYou saved my life ! Finally I was able to open a connection and to send a message to the server using Swift 5 and without to upgrade my macOS to Catalina ! Thank you ! P.S.: If you need to connect using TCP is also working this example, just change from UDP to TCP.
-
Ramcharan Reddy about 3 yearshow to make the connection to listen for continuously?