从Swift中的sockaddr_in结构获取IP地址和端口号?

时间:2017-01-05 20:49:31

标签: swift sockets sockaddr-in

经过多次试验和错误,但没有任何成功,似乎我可能需要一点帮助:

如何在最新版本的Swift中从sockaddr_in获取IP地址和端口号?

我看到了一些相关问题,但似乎无法在任何地方找到合适的例子。另外,我似乎并没有真正理解在Swift中如何处理C类型的结构和指针,这实际上并没有帮助。

任何人都可以向我提供有用资源的示例或链接吗?

非常感谢提前!

1 个答案:

答案 0 :(得分:3)

如果您需要IP地址和端口为数字,那么您可以 直接访问sockaddr_in的相应字段,但是 记得将值从网络字节(大端)转换为主机 字节顺序:

let saddr: sockAddr = ...

let port = in_port_t(bigEndian: sockAddr.sin_port)
let addr = in_addr_t(bigEndian: sockAddr.sin_addr.s_addr)

getnameinfo()可用于将IP地址提取为字符串 (以点分十进制表示法),以及可选的端口。 将struct sockaddr_in指针强制转换为struct sockaddr指针 在Swift中称为“重新绑定”,并使用withMemoryRebound()

完成
var sockAddr: sockaddr_in = ...

var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
var service = [CChar](repeating: 0, count: Int(NI_MAXSERV))

withUnsafePointer(to: &sockAddr) {
    $0.withMemoryRebound(to: sockaddr.self, capacity: 0) {
        _ = getnameinfo($0, socklen_t($0.pointee.sa_len),
                        &hostname, socklen_t(hostname.count),
                        &service, socklen_t(service.count),
                        NI_NUMERICHOST | NI_NUMERICSERV)
    }
}
print("addr:", hostname)
print("port:", service)

这适用于IPv4和IPv6套接字地址结构(sockaddr_insockaddr_in6)。

有关“不安全指针转换”的详细信息,请参阅 SE-0107 UnsafeRawPointer APIUnsafeRawPointer Migration。后一页包含如何处理的示例代码 Swift 3中的套接字地址。