7

I want to develop UDP client and send data in Swift.

I have reference the following link:

Swift: Receive UDP with GCDAsyncUdpSocket

Retrieving a string from a UDP server message

Swift UDP Connection

But I could not find a good way to implement UDP in Swift.

Can someone teach me How to implement UDP client and send data in Swift on iPhone?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Martin
  • 2,813
  • 11
  • 43
  • 66
  • Please clarify how your question is different to the [Swift UDP Connection](http://stackoverflow.com/questions/25876189/swift-udp-connection) one? It shows how to send data via UDP in Swift? – hnh Feb 03 '15 at 10:38
  • I can not understand the answer you post in [Swift UDP Connection](http://stackoverflow.com/questions/25876189/swift-udp-connection). Where can I put the data and IP address in the code? – Martin Feb 04 '15 at 06:27
  • This is how I got UDP to work in Swift: http://stackoverflow.com/questions/26790129/swift-receive-udp-with-gcdasyncudpsocket/26818254#26818254 – 0xRLA Feb 04 '15 at 08:42

4 Answers4

4

for me, I used this, and its usage:

broadcastConnection = UDPBroadcastConnection(port: 35602) { [unowned self] (response: (ipAddress: String, port: Int, response: [UInt8])) -> Void in
    print("Received from \(response.ipAddress):\(response.port):\n\n\(response.response)")
}
1

This looks like a dupe to Swift UDP Connection.

Refactoring the example a little bit:

let INADDR_ANY = in_addr(s_addr: 0)

udpSend("Hello World!", address: INADDR_ANY, port: 1337)

func udpSend(textToSend: String, address: in_addr, port: CUnsignedShort) {
  func htons(value: CUnsignedShort) -> CUnsignedShort {
    return (value << 8) + (value >> 8);
  }

  let fd = socket(AF_INET, SOCK_DGRAM, 0) // DGRAM makes it UDP

  var addr = sockaddr_in(
    sin_len:    __uint8_t(sizeof(sockaddr_in)),
    sin_family: sa_family_t(AF_INET),
    sin_port:   htons(port),
    sin_addr:   address,
    sin_zero:   ( 0, 0, 0, 0, 0, 0, 0, 0 )
  )

  textToSend.withCString { cstr -> Void in
    withUnsafePointer(&addr) { ptr -> Void in
      let addrptr = UnsafePointer<sockaddr>(ptr)
      sendto(fd, cstr, strlen(cstr), 0, addrptr, socklen_t(addr.sin_len))
    }
  }

  close(fd)
}

If you have the target IP as a string, use inet_pton() to convert it to an in_addr. Like so:

var addr = in_addr()
inet_pton(AF_INET, "192.168.0.1", &buf)

Feel free to steal code from over here: SwiftSockets

Oh, and if you plan to do any serious network programming, grab this book: Unix Network Programming

Community
  • 1
  • 1
hnh
  • 13,957
  • 6
  • 30
  • 40
  • Thanks for your reply , but if I want to send byte data. I already change the string to the byteArray like the code: var byteArray : `[Byte] = [0x55, 0xAA, 0x01] var data = " {\"SN\":\""+DeviceSN_text.text+"\",\"password\":\""+DevicePWD_text.text+"\"}" for char in data.utf8{ byteArray += [char] }` How to change the code ? – Martin Feb 05 '15 at 06:59
  • That should be easy for you to adapt. Instead of cstr/strlen just use the byte buffer you already have (and its length). – hnh Feb 07 '15 at 13:42
  • Where does it send? The address is.. 0? How would I change this to set a specific ip? – stackdaemon Jun 21 '16 at 12:32
  • This is covered in the answer: If you have the target IP as a string, use inet_pton() to convert it to an `in_addr`. – hnh Jun 21 '16 at 12:35
1

very nice sample! My two cents.. fixed for swift 4.2. / Xcode 10, (I love using 20 lines instead of a bunch of other files.. and Pods.. ). Added some more returned results.

import Foundation

func udpSend(textToSend: String, address: in_addr, port: CUnsignedShort) {


func htons(value: CUnsignedShort) -> CUnsignedShort {
    return (value << 8) + (value >> 8);
}

let fd = socket(AF_INET, SOCK_DGRAM, 0) // DGRAM makes it UDP

let addr = sockaddr_in(
    sin_len:    __uint8_t(MemoryLayout<sockaddr_in>.size),
    sin_family: sa_family_t(AF_INET),
    sin_port:   htons(value: port),
    sin_addr:   address,
    sin_zero:   ( 0, 0, 0, 0, 0, 0, 0, 0 )
)

let sent = textToSend.withCString { cstr -> Int in

    var localCopy = addr

    let sent = withUnsafePointer(to: &localCopy) { pointer -> Int in
        let memory = UnsafeRawPointer(pointer).bindMemory(to: sockaddr.self, capacity: 1)
        let sent = sendto(fd, cstr, strlen(cstr), 0, memory, socklen_t(addr.sin_len))
        return sent
    }

    return sent
}

close(fd)

}

ingconti
  • 10,876
  • 3
  • 61
  • 48
0

After pretty extensive research coming up with only basic pointers towards GCD's AsyncSocket, and being a pure Swift trained iOS programmer, I looked for something with native Swift socket support.

Thankfully, I found a much simpler alternative to using Async, called SwiftSocket.

The github (https://github.com/xyyc/SwiftSocket) has examples for most sockets, and is ready to use by copying just a few files into a project.

For swift-only devs, I feel its underutilized and will quickly replace Async for non-objective-c apps. Then again I'm pretty new to this stuff so I may be way off :D

Ash
  • 45
  • 9