I playing around with Apple's Reachabilitty
class in Swift.
The web server in my private Wi-Fi runs on http://10.0.0.1
. To check its reachability I want to use the following function from Reachability.h
(not the one with hostname):
/*!
* 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:
/*
* [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?
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.
You create a sockaddr_in
first:
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, e.g.
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
is the “common part”, and many socket functions which take a pointer to a sockaddr
as parameter.
In C you can simply cast between the pointers:
struct sockaddr sin;
// ...
struct sockaddr *addrPtr = (struct sockaddr *)&sin;
In Swift that is done more explicitly as “rebinding”. For more information, see
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With