简体   繁体   English

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

[英]Is it wise to use Reachability to check for a remote host's availability?

Is it wise to use Reachability Class(from Apple) to check for a remote host's availability ?使用 Reachability Class(来自 Apple)检查远程主机的可用性是否明智? say for example, www.google.com比如说,www.google.com

or should I use或者我应该使用

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

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

Which is the best option since I've heard that Reachability is having bug with checking for host's availability ?哪个是最好的选择,因为我听说Reachability 在检查主机可用性时有错误

Here is a good way to check if host is reachable:这是检查主机是否可达的好方法:

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

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

If host is offline you will receive some error code in error , nil in data and nil in response variables.如果主机离线,您将收到一些错误代码errornil datanil response变量。
If host is online and responds there will be some response , data , and error==nil .如果主机在线并响应,则会有一些responsedataerror==nil

As mentioned by others, reachability detects changes in your hardware instead of the real availability of a server.正如其他人所提到的,可达性检测的是硬件的变化,而不是服务器的实际可用性。 After reading many posts, I came up with this code.在阅读了很多帖子后,我想出了这段代码。

Here is a full implementation of a ReachabilityManager class that uses both Reachability and URLConnection to make sure that the connection is available or not.这是 ReachabilityManager 类的完整实现,它使用 Reachability 和 URLConnection 来确保连接可用或不可用。 Please note that depends on the Reachability classes (I am using the Tony Million implementation but I am sure it works with the Apple one)请注意,这取决于 Reachability 类(我使用的是 Tony Million 实现,但我确信它适用于 Apple 实现)

If you test this in the simulator and enable/disable your wireless connection you will see that it detects (sometimes takes a few seconds) the connection/disconnection.如果您在模拟器中测试并启用/禁用您的无线连接,您将看到它检测到(有时需要几秒钟)连接/断开连接。 Something that before with just the reachability class did not work.以前仅使用可达性类不起作用的东西。

I have also added a couple of notifications that are more effective than the ones from Reachability for the rest of your code.我还为您的其余代码添加了一些通知,这些通知比来自 Reachability 的通知更有效。 You may want to handle this in a different way.您可能希望以不同的方式处理此问题。

Also, this is a singleton so you can instantiate if from anywhere.此外,这是一个单例,因此您可以从任何地方实例化。 You can convert it to a non static class and instantiate it from the AppDelegate.您可以将其转换为非静态类并从 AppDelegate 实例化它。

If a reader has time to create some UnitTests for it, let me know, so we can share more knowledge around the Reachability.如果读者有时间为其创建一些单元测试,请告诉我,以便我们可以分享更多有关可达性的知识。

Just create a new NSObject class and copy this contents:只需创建一个新的 NSObject 类并复制以下内容:

.h 。H

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

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

@end

.m .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

Reachability will not tell you if a remote host is contactable.可达性不会告诉您远程主机是否可联系。 It only tests the first hop ie can you send a packet to your router.它只测试第一跳,即您能否向路由器发送数据包。 If the router cannot reach the wider internet, reachability will still tell you that you have a wifi connection.如果路由器无法连接到更广泛的互联网,可达性仍会告诉您您有 wifi 连接。 You have to implement one of the other suggested solutions to test "true" reachability.您必须实施其他建议的解决方案之一来测试“真正的”可达性。

It is wise to check if you have any internet connection first, and for that I use Reachability.明智的做法是先检查您是否有任何互联网连接,为此我使用 Reachability。 And I try to do my connection with the server only I have internet.我尝试与服务器建立连接,只有我有互联网。

Here is a tutorial on how to use Reachability.这是有关如何使用 Reachability 的教程。 http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/ 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

The code you provided should also work but might not give the desired result.. Reachability is more reliable..您提供的代码也应该有效,但可能无法提供所需的结果。可达性更可靠。

The following code from developer.apple.com might help you.. 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.

}

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

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