如何从Swift的DNS查询中获取真实的IP地址?

Hri*_*sov 10 dns ip-address swift

我想从DNS查询中获取IP连衣裙(如192.168.0.1或87.12.56.50)Swift.我用100种不同的方法尝试了100次......没有什么能帮助我,所以我必须寻求帮助(我希望这里有很多人;))这是我的代码到目前为止:

let host = CFHostCreateWithName(nil,"subdomain.of.stackoverflow.com").takeUnretainedValue();
CFHostStartInfoResolution(host, .Addresses, nil);
var success: Boolean = 0;
let addresses = CFHostGetAddressing(host, &success).takeUnretainedValue() as NSArray;
if(addresses.count > 0){
   let theAddress = addresses[0] as NSData;
   println(theAddress);
}
Run Code Online (Sandbox Code Playgroud)

好的......这些是我试图实现但没有成功的代码的链接:https: //gist.github.com/mikeash/bca3a341db74221625f5
如何在iOS上执行DNS查询
从NSData对象在Swift中创建数组
CFHostGetAddressing( )支持ipv6 DNS条目?
在Swift中进行简单的DNS查找
如果我们对这个问题进行了无意义的否定投票,我们可以尝试找到解决方案并帮助其他人(比如我)

Mar*_*n R 30

您的代码将地址检索为"套接字地址"结构. getnameinfo()可用于将地址转换为数字IP字符串(从/sf/answers/1793928181/回收的代码,现在更新为Swift 2):

let host = CFHostCreateWithName(nil,"www.google.com").takeRetainedValue()
CFHostStartInfoResolution(host, .Addresses, nil)
var success: DarwinBoolean = false
if let addresses = CFHostGetAddressing(host, &success)?.takeUnretainedValue() as NSArray?,
    let theAddress = addresses.firstObject as? NSData {
    var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
    if getnameinfo(UnsafePointer(theAddress.bytes), socklen_t(theAddress.length),
        &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
            if let numAddress = String.fromCString(hostname) {
                print(numAddress)
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(例子): 173.194.112.147

还要注意takeRetainedValue()第一行中的用法,因为 CFHostCreateWithName()在其名称中有"Create"因此返回一个(+1)保留对象.


Swift 3/Xcode 8的更新:

let host = CFHostCreateWithName(nil,"www.google.com" as CFString).takeRetainedValue()
CFHostStartInfoResolution(host, .addresses, nil)
var success: DarwinBoolean = false
if let addresses = CFHostGetAddressing(host, &success)?.takeUnretainedValue() as NSArray?,
    let theAddress = addresses.firstObject as? NSData {
    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
    if getnameinfo(theAddress.bytes.assumingMemoryBound(to: sockaddr.self), socklen_t(theAddress.length),
                   &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
        let numAddress = String(cString: hostname)
        print(numAddress)
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,获取主机的所有 IP地址:

let host = CFHostCreateWithName(nil,"www.google.com" as CFString).takeRetainedValue()
CFHostStartInfoResolution(host, .addresses, nil)
var success: DarwinBoolean = false
if let addresses = CFHostGetAddressing(host, &success)?.takeUnretainedValue() as NSArray? {
    for case let theAddress as NSData in addresses {
        var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
        if getnameinfo(theAddress.bytes.assumingMemoryBound(to: sockaddr.self), socklen_t(theAddress.length),
                       &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
            let numAddress = String(cString: hostname)
            print(numAddress)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我遇到了一个问题.例如,如果主机名字符串是`hello`,则程序崩溃说'致命错误:在展开Optional值时意外发现nil'. (2认同)