Swift 3如何解决NetService IP?

Web*_*Lai 5 ipv4 nsnetservice ios nsnetservicebrowser swift3

只是在快速尝试Bonjour 3

这是我的代码,我可以收到代表

func netServiceDidResolveAddress(_ sender: NetService) {
 print("netServiceDidResolveAddress service name \(sender.name) of type \(sender.type)," +
                "port \(sender.port), addresses \(sender.addresses)")
}
Run Code Online (Sandbox Code Playgroud)

这是我的结果

netServiceDidResolveAddress服务名称Webber的Mac mini类型_myapp._tcp.,端口5678,地址可选([<1002162e c0a80205 00000000 00000000>,<1c1e162e 00000000 fe800000 00000000 00bce7ad 24b4b7e8 08000000>])

c0a80205是我要查找的IP => 192.168.2.5

Apple说,地址是[数据]

服务的地址.这是NSData实例的NSArray,每个实例都包含一个适用于connect(2)的struct sockaddr.如果没有为服务解析地址或服务尚未解析,则返回空的NSArray.

我仍然混淆为什么数据不能使用.btyes?正如Apple所说"这是NSData实例的NSArray"但我不能像NSData一样使用它

以及如何将地址解析为可读IP字符串?

我以前试过这个,但是除了......之外我没有得到结果.

let thedata = NSData(bytes: sender.addresses, length: (sender.addresses?.count)!)
var storage = sockaddr_storage()
thedata.getBytes(&storage, length: sizeof(sockaddr_storage))

if Int32(storage.ss_family) == AF_INET {
    let addr4 = withUnsafePointer(&storage) {UnsafePointer<sockaddr_in>($0).pointee }
    print(inet_ntoa(addr4.sin_addr));
}
Run Code Online (Sandbox Code Playgroud)

任何建议都会有所帮助,谢谢

Phi*_*ole 14

这是我在Swift 3中的表现.

func netServiceDidResolveAddress(_ sender: NetService) {
    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
    guard let data = sender.addresses?.first else { return }
    data.withUnsafeBytes { (pointer:UnsafePointer<sockaddr>) -> Void in
        guard getnameinfo(pointer, socklen_t(data.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else {
            return
        }
    }
    let ipAddress = String(cString:hostname)
    print(ipAddress)
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*247 6

已编辑 Phil Coles 对 Swift 5.0 无警告解决方案的回答:

func netServiceDidResolveAddress(_ sender: NetService) {
        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
        guard let data = sender.addresses?.first else { return }
        data.withUnsafeBytes { ptr in
            guard let sockaddr_ptr = ptr.baseAddress?.assumingMemoryBound(to: sockaddr.self) else {
                // handle error
                return
            }
            var sockaddr = sockaddr_ptr.pointee
            guard getnameinfo(sockaddr_ptr, socklen_t(sockaddr.sa_len), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else {
                return
            }
        }
        let ipAddress = String(cString:hostname)
        print(ipAddress)
    }
Run Code Online (Sandbox Code Playgroud)


Web*_*Lai 4

好吧...这不是一个聪明的答案,至少我可以获得可读的IP

只需使用此函数即可获取 IP 字符串

let bonjourDevices = [NetService]()

let bonjourDevice = bonjourDevices[0] 

let host = self.getIPV4StringfromAddress(address:bonjourDevice.addresses!)


func getIPV4StringfromAddress(address: [Data] , port : Int ) -> String{

        let data = address.first! as NSData;

        var ip1 = UInt8(0)
        data.getBytes(&ip1, range: NSMakeRange(4, 1))

        var ip2 = UInt8(0)
        data.getBytes(&ip2, range: NSMakeRange(5, 1))

        var ip3 = UInt8(0)
        data.getBytes(&ip3, range: NSMakeRange(6, 1))

        var ip4 = UInt8(0)
        data.getBytes(&ip4, range: NSMakeRange(7, 1))

        let ipStr = String(format: "%d.%d.%d.%d:%d",ip1,ip2,ip3,ip4,port);

        return ipStr;
    }
Run Code Online (Sandbox Code Playgroud)