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

След много проби и грешки и без никакъв успех, изглежда, че може да имам нужда от малко помощ по този въпрос:

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

Видях някои свързани въпроси, но изглежда не мога да намеря подходящ пример никъде. Освен това не изглежда да разбирам как структурите и указателите от тип C трябва да се обработват в Swift, което всъщност не помага.

Може ли някой да ми предостави пример или връзка към полезни ресурси?

Много благодаря предварително!


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


Отговори (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 API на UnsafeRawPointer и Миграция на UnsafeRawPointer. Последната страница съдържа примерен код за обработка на адреси на сокет в Swift 3.

person Martin R    schedule 05.01.2017