0

currently I am using GCDAsyncUdpSocket to send a udp broadcast. Currently, the code sends it to a hardcoded 255.255.255.255 address. Is that the correct broadcast address on all networks? Will it fail on certain networks? What is the correct swift code?

socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
socket!.send(ipRequestData!, toHost: "255.255.255.255", port: discoveryPort, withTimeout: 10000, tag: 0)

This question has an answer but it is in Objective-C Calculating the Broadcast Address in Objective-C

gregm
  • 12,019
  • 7
  • 56
  • 78

1 Answers1

0

Your broadcast address depends on your host address and the subnet mask. You can find the formula to calculate the broadcast address on Wikipedia:

broadcastAddress = ipAddress | ~subnetMask

You can calculate it with the following function:

func calculateBroadcastAddress(ipAddress: String, subnetMask: String) -> String {
    let ipAdressArray = ipAddress.split(separator: ".")
    let subnetMaskArray = subnetMask.split(separator: ".")
    guard ipAdressArray.count == 4 && subnetMaskArray.count == 4 else {
        return "255.255.255.255"
    }
    var broadcastAddressArray = [String]()
    for i in 0..<4 {
        let ipAddressByte = UInt8(ipAdressArray[i]) ?? 0
        let subnetMaskbyte = UInt8(subnetMaskArray[i]) ?? 0
        let broadcastAddressByte = ipAddressByte | ~subnetMaskbyte
        broadcastAddressArray.append(String(broadcastAddressByte))
    }
    return broadcastAddressArray.joined(separator: ".")
}

Example:

let broadcastAddress = calculateBroadcastAddress(ipAddress: "172.16.0.0", subnetMask: "255.240.0.0")

Result:

"172.31.255.255"

In general, you should never choose the main queue for network operations because it will lead to lags in the user interface (which is drawn in the main queue). Better use

let udpSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.global())

Do not forget to explicitly enable broadcasts for this socket

do {
    try udpSocket?.enableBroadcast(true)
} catch let error {
    print(error)
}

Also consider that Apple enforces an iOS app to work with IPv6, which does not support broadcasts but multicasts. So maybe you should switch to multicasts at least if your device is inside a pure IPv6 network.

sundance
  • 2,930
  • 1
  • 20
  • 25
  • Also. Does my code appear to be doing a multicast or a broadcast? – gregm Jan 26 '18 at 16:03
  • I added the Swift code to my answer. I do not understand your second question. You are sending to 255.255.255.255, which is definitely a broadcast address. – sundance Jan 28 '18 at 12:31
  • Will 255.255.255.255 work on all WiFi networks or will some networks require using a different address for broadcasts? – gregm Jan 28 '18 at 12:43
  • This depends on your network topology. Please really read the Wikipedia article to understand how broadcasts work. – sundance Jan 28 '18 at 12:51
  • thank you much. Getting ip address and subnet mask seem to be also some complicated code. – gregm Jan 29 '18 at 13:45
  • according to the wikipedia article 255 should send to the local network just fine it seems – gregm Jan 29 '18 at 13:48