Инициируйте структуру `sockaddr` с заданным IP-адресом в Swift.

Я играю с классом Apple Reachabilitty в Swift.

Веб-сервер в моем частном Wi-Fi работает на http://10.0.0.1. Чтобы проверить его доступность, я хочу использовать следующую функцию из Reachability.h (не ту, что с именем хоста):

/*!
 * Use to check the reachability of a given IP address.
 */
+ (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

Я sockaddr выглядит соответственно socket.h так:

/*
 * [XSI] Structure used by kernel to store most addresses.
 */
struct sockaddr {
    __uint8_t   sa_len;     /* total length */
    sa_family_t sa_family;  /* [XSI] address family */
    char        sa_data[14];    /* [XSI] addr value (actually larger) */
};

Как я могу создать структуру sockaddr с IP-адресом 10.0.0.1 в Swift?

Я уже читал [здесь] что-то о UnsafePointer и UnsafeMutablePointer и что Массивы C (или в данном случае это массив Objective-C?) в Swift представлены в виде кортежей, но я до сих пор точно не знаю, как с ними работать.


person winklerrr    schedule 23.03.2018    source источник


Ответы (1)


Сначала вы создаете sockaddr_in:

var addr = sockaddr_in()
addr.sin_len = UInt8(MemoryLayout.size(ofValue: addr))
addr.sin_family = sa_family_t(AF_INET)

addr.sin_addr.s_addr = inet_addr("10.0.0.1")
// Alternatively:
inet_pton(AF_INET, "10.0.0.1", &addr.sin_addr)

а затем «перепривязать» его к указателю sockaddr, например.

let reachability = withUnsafePointer(to: &addr, {
    $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
        SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, $0)
    }
})

Некоторое объяснение:

Существуют разные типы адресов для разных семейств адресов (например, struct sockaddr_in для IPv4, struct sockaddr_in6 для IPv6). struct sockaddr — это «общая часть», и многие функции сокетов принимают указатель на sockaddr в качестве параметра.

В C вы можете просто бросить между указателями:

struct sockaddr sin;
// ...
struct sockaddr *addrPtr = (struct sockaddr *)&sin;

В Swift это делается более явно как «перепривязка». Для получения дополнительной информации см.

person Martin R    schedule 23.03.2018