简体   繁体   English

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

[英]Init a `sockaddr` struct with a given IP address in Swift

I playing around with Apple's Reachabilitty class in Swift. 我在Swift玩Apple的Reachabilitty课程。

The web server in my private Wi-Fi runs on http://10.0.0.1 . 我的私人Wi-Fi中的Web服务器运行在http://10.0.0.1 To check its reachability I want to use the following function from Reachability.h (not the one with hostname): 为了检查它的可达性,我想使用Reachability.h的以下函数(不是带有主机名的函数):

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

I sockaddr looks accordingly to socket.h like this: 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) */
};

How can I create a sockaddr struct with th ip address 10.0.0.1 in Swift? 如何在Swift中使用ip地址10.0.0.1创建一个sockaddr结构?

I already read [ here ] something about UnsafePointer and UnsafeMutablePointer and that C arrays (or is it in this case an Objective-C array?) are represented as tuples in Swift, but I still don't know for sure how to work with them. 我已经读过[ 这里 ]关于UnsafePointerUnsafeMutablePointer东西,那些C数组(或者它在这种情况下是一个Objective-C数组?)在Swift中表示为元组,但我仍然不知道如何使用它们。

You create a sockaddr_in first: 首先创建一个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)

and then "rebind" it to a sockaddr pointer, eg 然后将它“重新绑定”到一个sockaddr指针,例如

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

Some explanation: 一些解释:

There are different address types for different address families (such as struct sockaddr_in for IPv4, struct sockaddr_in6 for IPv6). 有不同的地址类型不同的地址族(如struct sockaddr_in对于IPv4, struct sockaddr_in6对IPv6)。 struct sockaddr is the “common part”, and many socket functions which take a pointer to a sockaddr as parameter. struct sockaddr是“公共部分”,以及许多socket函数,它们将指向sockaddr的指针作为参数。

In C you can simply cast between the pointers: 在C中你可以简单地在指针之间施放:

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

In Swift that is done more explicitly as “rebinding”. 在Swift中,更明确地将其称为“重新绑定”。 For more information, see 有关更多信息,请参阅

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM