Cocoa:如何在 Swift 中获取广播 IP 地址?

Posted

技术标签:

【中文标题】Cocoa:如何在 Swift 中获取广播 IP 地址?【英文标题】:Cocoa: How to get broadcast IP address in Swift? 【发布时间】:2021-12-09 12:57:19 【问题描述】:

您好,我可以使用this solution 获取本地网络 IP 地址。我尝试使用此解决方案通过 this Objective-C solution 获取广播 IP 地址。

static func getBroadCastAddress() -> String? 
        var address: String?
            var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
            if getifaddrs(&ifaddr) == 0 
                var ptr = ifaddr
                while ptr != nil 
                    defer  ptr = ptr?.pointee.ifa_next 

                    guard let interface = ptr?.pointee else  return "" 
                    let addrFamily = interface.ifa_addr.pointee.sa_family
                    if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) 
 
                        let name: String = String(cString: (interface.ifa_name))
                        if  name == "en0" || name == "en2" || name == "en3" || name == "en4" || name == "pdp_ip0" || name == "pdp_ip1" || name == "pdp_ip2" || name == "pdp_ip3" 
                            var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                            getnameinfo(interface.ifa_addr, socklen_t((interface.ifa_addr.pointee.sa_len)), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST)
                            
//                            inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)
                             
                            if let sinAddress = (interface.ifa_dstaddr as? sockaddr_in)?.sin_addr //=> It's always fail
                                
                                
                                address = String(utf8String: inet_ntoa(sinAddress))
                            
                            
                        
                    
                
                freeifaddrs(ifaddr)
            
            return address ?? ""
    

问题是我不能像目标 c 代码中的 inet_ntoa(((struct sockaddr_in *)temp_addr-&gt;ifa_dstaddr)-&gt;sin_addr) 那样从 interface 得到 sin_addr

谁能帮助我使用 Swift 在 Cocoa 中获取广播 IP 地址?感谢您的宝贵时间。

【问题讨论】:

对于您提供的代码示例,什么不起作用?如果您使用调试器单步调试,示例会在哪里遇到问题? @ScottThompson 已更新。谢谢你的提及。 【参考方案1】:
let acceptedInterfaces = ["en0", "en2", "en3", "en4", "pdp_ip0", "pdp_ip1", "pdp_ip2", "pdp_ip3"]
func getBroadCastAddress() 
    var interfaceAddresses : [String : String] = [:]
    var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil

    if getifaddrs(&ifaddr) == 0 
        defer  freeifaddrs(ifaddr) 

        var currentInterface = ifaddr
        while currentInterface != nil 
            defer  currentInterface = currentInterface!.pointee.ifa_next 

            let interface = currentInterface!.pointee
            let addrFamily = interface.ifa_addr.pointee.sa_family
            guard addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) else  continue 

            let interfaceName = String(cString: interface.ifa_name)
            if acceptedInterfaces.contains(interfaceName) 
                currentInterface!.withMemoryRebound(to: sockaddr_in.self, capacity: 1) 
                    sockaddr in

                    if let addressCString = inet_ntoa(sockaddr.pointee.sin_addr) 
                        interfaceAddresses[interfaceName] = String(cString: addressCString)
                    
                
            
        
    

    debugPrint(interfaceAddresses)

打印出来:

["en0": "194.127.0.0"]

【讨论】:

谢谢,我测试了解决方案。当我在终端中使用命令ifconfig 时,广播IP 将为172.20.10.15,但在程序中为1.0.0.0。有什么办法可以得到正确的IP? 您的代码正在查看if name == "en0" || name == ... 所涵盖的集合中所有接口的地址,它可能会返回它找到的最后一个此类地址。您要查找哪个接口的广播地址?尝试将print(address) 放在address = addressString 的正上方,您可以看到正在生成的所有地址。 是的,在你告诉我的条件之前,我确实喜欢过。它给了我一堆 1.0.0.0 地址。我想我必须使用 shell 命令。

以上是关于Cocoa:如何在 Swift 中获取广播 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Storyboards/Cocoa 在 Swift 3.x 中引用视图的窗口

如何使用 Cocoa (Mac) 在 Swift 中创建 PDF

图书┃Swift与Cocoa框架开发

使用 boost::asio 获取广播源 IP 地址

Swift / Cocoa:如何观察文件夹的变化?

如何将NSNib.Name传递给Swift / Cocoa中的窗口控制器