Получение IP-адреса и номера порта из структуры sockaddr_in в Swift?

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

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

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

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

Спасибо заранее!


person Thomas De Reyck    schedule 05.01.2017    source источник


Ответы (1)


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

Дополнительные сведения о «небезопасных преобразованиях указателей» см. в разделе SE. -0107 UnsafeRawPointer API и перенос UnsafeRawPointer. Последняя страница содержит пример кода, как обрабатывать адреса сокетов в Swift 3.

person Martin R    schedule 05.01.2017