碰到的问题:
如果传入的 hostname 带有 http prefix,则有网络也会返回 not reach。如果没有 http,则是正常的。
[Reachability reachabilityWithHostName:@"http://www.baidu.com"];
正取的写法应该是只有 hostName:
[Reachability reachabilityWithHostName:@"www.baidu.com"];
苹果官方文档:
1、NetworkingOverview
2、苹果官方 demo Reachability
3、用到的底层库 SCNetworkReachability
文档中解释:
The SCNetworkReachability programming interface allows an application to determine the status of a system's current network configuration and the reachability of a target host. A remote host is considered reachable when a data packet, sent by an application into the network stack, can leave the local device. Reachability does not guarantee that the data packet will actually be received by the host.
所以说,Reachability 在监测的时候,并没有发送任何请求,只是判断数据包能不能离开本机。很有可能是通过 DNS 解析域名,如果成功则 reach,否则 not reach。(很有可能有缓存的 DNS 列表)
如果需要监测 host 真实可达,则准确的做法应该创建一个 network connection。
参考其他解释:
Having thought about it, this is probably the correct behaviour if you view SCNetworkReachability as running at the TCP/IP level, not at the HTTP level, in the same way that ping google.com on a Mac/PC behind a corporate firewall doesn't work either. The HTTP proxy (as the name implies) is for the HTTP protocol, not the whole TCP/IP stack.
3、另外一种解释(比较赞同)
The explanation clears that iOS system doesn't send any request to outside world to check the reachability. It just tells that data packet can leave the device or not. If system were to send the request it automatically means that it is connected to network.
You can verify this by mentioning a valid host like "www.stackoverflow.com" and check in charles (first unblock it) that no request is sent.You can also check with other valid host names like "www.abcdefgh.com" (verify this by running it in Safari and see in charles) it also gives you the reachability but charles shows no request.Also if you put http:// before any valid host, something like "http://www.stackoverflow.com" it will also fails reachability. So it is clear that it is not an outgoing http request. If system has to send a request outside then what's the point of providing the class? A developer could have created a network connection and try to connect to a host and see if it passes or fails.
However it is interesting that if an invalid host like "www.hjjkhkhk.com" is provided iOS system gives reachability as false. Now the question is how iOS system finds a valid or invalid host without sending any query to outside world? May be it is periodically caching a list of DNS ranges??? Highly improbable to me.
苹果也没给个官方解释,这个到底是怎么实现的~~~