在Swift中使用给定的IP地址初始化`sockaddr`结构

时间:2018-03-23 18:28:48

标签: ios objective-c swift objective-c-swift-bridge

我在Swift中玩Apple的Reachabilitty课程。

我的私人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) */
};

如何在Swift中使用ip地址sockaddr创建10.0.0.1结构?

我已经读过[here]关于UnsafePointerUnsafeMutablePointer的内容,那些C数组(或者在这种情况下是Objective-C数组?)在Swift中表示为元组,但我仍然不确定如何使用它们。

1 个答案:

答案 0 :(得分:4)

首先创建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)
    }
})

一些解释:

不同的地址系列有不同的地址类型(例如IPv4的struct sockaddr_in,IPv6的struct sockaddr_in6struct sockaddr是“公共部分”,还有许多套接字函数将指针sockaddr作为参数。

在C中你可以简单地在指针之间施放:

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

在Swift中,更明确地将其称为“重新绑定”。 有关更多信息,请参阅