如何使用 Swift 获取我的 wifi 网络的广播地址?

How do I get the broadcast address of my wifi network using Swift?

目前我正在使用 GCDAsyncUdpSocket 发送 udp 广播。目前,代码将其发送到硬编码的 255.255.255.255 地址。这是所有网络上的正确广播地址吗?它会在某些网络上失败吗?正确的 swift 代码是什么?

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

这个问题有答案但是在Objective-C Calculating the Broadcast Address in Objective-C

您的广播地址取决于您的主机地址和子网掩码。您可以在 Wikipedia:

上找到计算广播地址的公式
broadcastAddress = ipAddress | ~subnetMask

您可以使用以下函数计算:

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: ".")
}

示例:

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

结果:

"172.31.255.255"

一般来说,您永远不应该选择 main 队列进行网络操作,因为它会导致用户界面(在主队列中绘制)出现滞后。更好用

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

不要忘记为此套接字显式启用广播

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

还要考虑到 Apple 强制 iOS 应用程序使用 IPv6,它不支持广播但 multicasts。因此,至少如果您的设备位于纯 IPv6 网络中,也许您应该切换到多播。