Если вам нужен 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_in
и).
Для получения дополнительной информации о "небезопасном преобразовании указателей", см SE-0107 UnsafeRawPointer API и UnsafeRawPointer Migration. Последняя страница содержит пример кода, как обращаться с адресами в Swift 3.