使用Reachability检查远程主机的可用性是否明智?

时间:2011-01-21 07:23:55

标签: iphone reachability

使用Reachability Class(来自Apple)检查远程主机的可用性是否明智?例如,www.google.com

或者我应该使用

NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"]]; 

if ([connectedString length] != 0) // Host Available

最佳选择,因为我听说可访问性存在检查主机可用性的错误

6 个答案:

答案 0 :(得分:10)

这是检查主机是否可访问的好方法:

    NSURLResponse *response=nil;
    NSError *error=nil;
    NSData *data = nil;
    NSURLRequest *request = [NSURLRequest requestWithURL:your_url];

    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

如果主机处于离线状态,您会在errornil中的datanil变量中的response收到一些错误代码。
如果主持人在线并做出回应,则会有一些responsedataerror==nil

答案 1 :(得分:3)

可达性不会告诉您远程主机是否可联系。它只测试第一跳,即你可以发送一个数据包到您的路由器。如果路由器无法访问更广泛的互联网,可达性仍将告诉您有wifi连接。您必须实现其他建议的解决方案之一来测试“真正的”可达性。

答案 2 :(得分:3)

正如其他人所提到的,可达性可检测硬件的变化,而不是服务器的实际可用性。在阅读了很多帖子后,我想到了这段代码。

这是ReachabilityManager类的完整实现,它使用Reachability和URLConnection来确保连接是否可用。请注意,这取决于Reachability类(我正在使用Tony Million实现,但我相信它可以与Apple一起使用)

如果您在模拟器中测试并启用/禁用无线连接,您将看到它检测到(有时需要几秒钟)连接/断开连接。之前只有可达性类的东西不起作用。

我还添加了一些通知,这些通知比其他代码的Reachability更有效。您可能希望以不同的方式处理此问题。

此外,这是一个单例,因此您可以从任何地方实例化。您可以将其转换为非静态类,并从AppDelegate实例化它。

我希望这对任何打破她/他的人有用的原因是可达性没有正确检测到可用性。

如果你们有时间为它创建一些单元测试,请告诉我们,以便我们可以分享有关可达性的更多知识。

只需创建一个新的NSObject类并复制此内容:

·H

#import <Foundation/Foundation.h>
@interface ReachabilityManager : NSObject

+ (void)startReachabilityWithHost : (NSURL *)hostName;

@end

的.m

#import "ReachabilityManager.h"
#import "Reachability.h"

@implementation ReachabilityManager

static ReachabilityManager *_sharedReachabilityManager;
static Reachability *reachability;
static NSURL *_hostName;
static BOOL isServerReachable;
+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        _sharedReachabilityManager = [[ReachabilityManager alloc] init];
    }
}

+ (void)startReachabilityWithHost : (NSURL *)hostName{
    _hostName = hostName;

    reachability = [Reachability reachabilityWithHostname:hostName.host];

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

+ (void)stopReachability{
    [reachability stopNotifier];
    [[NSNotificationCenter defaultCenter]removeObserver:kReachabilityChangedNotification];
}

+(void)reachabilityChanged: (NSNotification *)notification{
    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL isServerCurrentlyReachable = NO;
        do{
            isServerCurrentlyReachable = [self checkConnectivityToServer];
            BOOL wasServerPreviouslyReachable = isServerReachable;
            isServerReachable = isServerCurrentlyReachable;

            if (NO == wasServerPreviouslyReachable && YES == isServerCurrentlyReachable)
            {
                NSLog(@"REACHABLE!");
                [[NSNotificationCenter defaultCenter]postNotificationName:@"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:YES]];
            }
            else if (YES == wasServerPreviouslyReachable && NO == isServerCurrentlyReachable)
            {
                NSLog(@"UNREACHABLE!");
                [[NSNotificationCenter defaultCenter]postNotificationName:@"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:NO]];
            }
            [NSThread sleepForTimeInterval:5.0];
        }while(!isServerCurrentlyReachable);
    });

}


+(BOOL)checkConnectivityToServer{
    NSURLResponse *response;
    NSError *error=nil;
    NSData *data = nil;
    NSURLRequest *request = [NSURLRequest requestWithURL:_hostName];

    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    return (data && response);

}


@end

答案 3 :(得分:1)

最好先检查一下你是否有任何互联网连接,为此我使用了可达性。我尝试与服务器建立联系,只有我有互联网。

答案 4 :(得分:0)

以下是有关如何使用可达性的教程。 http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/

NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"]]; 

if ([connectedString length] != 0) // Host Available

您提供的代码也应该有效但可能无法提供所需的结果。可达性更可靠..

答案 5 :(得分:0)

developer.apple.com中的以下代码可能会对您有所帮助..

// Create the request.

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]

                        cachePolicy:NSURLRequestUseProtocolCachePolicy

                    timeoutInterval:60.0];

// create the connection with the request

// and start loading the data

NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

if (theConnection) {

    // Create the NSMutableData to hold the received data.

    // receivedData is an instance variable declared elsewhere.

    receivedData = [[NSMutableData data] retain];

} else {

    // Inform the user that the connection failed.

}
相关问题