即使主机名不存在,可达性也会返回主机可达

Posted

技术标签:

【中文标题】即使主机名不存在,可达性也会返回主机可达【英文标题】:reachability returns host reachable even when a host name is non-existant 【发布时间】:2012-02-19 23:15:52 【问题描述】:

关于可达性的许多问题,但似乎没有人遇到我遇到的问题...... 正如许多示例所示,我以这种方式使用可达性:

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil];

hostReach = [[Reachability reachabilityWithHostName: @"www.google.com"] retain];
[hostReach startNotifier];
[self updateInterfaceWithReachability: hostReach];

这很好用。但是,如果我将主机名更改为不存在的主机名,例如 www.nonexistanthostforsure.com,可达性仍然具有主机可达性。现在,阅读苹果文档,我的印象是可达性无法告诉我主机(服务器)是否在线。在这种情况下,结果是有道理的,但问题是为什么要打扰主机名呢?

【问题讨论】:

【参考方案1】:

何必纠结主机名呢?

我同意。

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil];

hostReach = [[Reachability reachabilityForInternetConnection] retain];
[hostReach startNotifier];
[self updateInterfaceWithReachability: hostReach];

Apple Reachability docs 状态:

reachabilityForInternetConnection- 检查默认路由是否可用。 应该由不连接到特定主机的应用程序使用

如果您检查默认路由是否可用,然后轮询您的服务器并且连接超时,您仍然可以执行诸如显示“无法连接到服务器”消息之类的操作,而无需针对特定主机名测试可达性。它基本上完成了同样的事情,只是它更自然,因为错误处理代码位于轮询代码的中间,因此您不必为它调用全局可达性处理程序。

【讨论】:

感谢您的回答。我似乎无法找到可靠的东西来检查服务器是否在线。我试过: NSURLResponse *response=nil;NSError *error=nil; NSData *data = nil; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"nonexistantserver.com/"]]; data = [NSURLConnection sendSynchronousRequest:request returnedResponse:&response error:&error]; 但即使这样也不返回错误,返回的数据和响应也不为零!必须做一些可靠的东西来检查服务器是否打开。 有更可靠的可达性代码here 再次感谢您帮助我。但是,我仍然有同样的问题。即使您建议的可达性版本也无法满足我的需求 - 能够判断我的服务器是否已启动!而且我在之前的评论中发布的代码也没有帮助(NSURLConnection),因为即使我使用不存在的服务器,它也不会失败。有人可以帮忙吗?【参考方案2】:

您是否尝试在该服务器上打开一个 TCP/IP 普通套接字到端口 21?如果成功,你就会知道主机在线....

【讨论】:

【参考方案3】:

Reachability 仅检查您的主机 url 请求是否可以从您的设备逃逸到您的路由器,它不确认您的请求是否到达实际服务器

我认为检查主机地址可用性的最佳方法是检查 NSURL 请求的结果。

NSString *url= @"http://google.com";
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:reqURL]];
NSURLResponse *resp = nil;
NSError *error = nil;
NSData *response = [NSURLConnection sendSynchronousRequest: theRequest returningResponse: &resp error: &error];
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];

使用这段代码,如果您的设备无法访问提供的 URL,它会向错误变量提供一些输出,如果它可以访问 URL 请求,则错误为 Nil。

即使您的 URL 数据包可以从您的设备路由出去并且永远不会到达主机服务器,可达性也会提供积极的输出。

【讨论】:

以上是关于即使主机名不存在,可达性也会返回主机可达的主要内容,如果未能解决你的问题,请参考以下文章

即使服务器的主机密钥存在于 known_hosts 文件中,JSch 连接也会因 UnknownHostKey 而失败

可达性解析主机名但无法ping通主机名

删除主机时,iOS 可达性无法识别

尽管有 4G,但一台设备的可达性返回“NotReachable”

可达性 + UIAlertView + 误报

即使主机健康且能够处理请求,ELB 也会返回 HTTP 504 错误