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

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

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

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

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

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

1 ответ

Решение

Если вам нужны IP-адрес и порт в виде чисел, вы можете получить доступ к соответствующим полям sockaddr_in напрямую, но не забудьте преобразовать значения из сетевого байта (big endian) в порядок байтов хоста:

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 Migration. Последняя страница содержит пример кода, как обрабатывать адреса сокетов в Swift 3.

Другие вопросы по тегам