2017-01-05 5 views
0

После долгих проб и ошибок, и без какого-либо успеха, мне кажется, я, возможно, потребуется немного помочь в этом один:Получение IP-адреса и номера порта из sockaddr_in структуры в Swift?

Как я могу получить IP-адрес и номер порта из sockaddr_in в последней версии Swift?

Я видел некоторые связанные вопросы, но не могу найти подходящий пример в любом месте. Кроме того, я действительно не понимаю, как C-структуры и указатели нужно обрабатывать в Swift, что на самом деле не помогает.

Может ли кто-нибудь подарить мне пример или ссылку на полезные ресурсы?

Большое спасибо заранее!

ответ

2

Если вам нужен 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.