【问题标题】:How to determine Internet Connection in Cocoa?如何确定 Cocoa 中的 Internet 连接?
【发布时间】:2011-11-29 10:26:44
【问题描述】:

我需要确定 Internet 连接是否可用。我不在乎它是如何连接的(WI-FI、Lan 等)。我需要确定,互联网连接是否可用。

附:我找到了一种检查 WI-FI 连接的方法。但我不在乎它是如何连接的(我需要检查所有可以连接到互联网的方式)。

类似 (isConnected) 的东西

【问题讨论】:

标签: objective-c macos cocoa


【解决方案1】:

我希望此代码适用于 iOS 和 OSX 平台。

#include <SystemConfiguration/SystemConfiguration.h>
static BOOL isInternetConnection()
{
    BOOL returnValue = NO;

#ifdef TARGET_OS_MAC

    struct sockaddr zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sa_len = sizeof(zeroAddress);
    zeroAddress.sa_family = AF_INET;

    SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithAddress(NULL, (const struct sockaddr*)&zeroAddress);


#elif TARGET_OS_IPHONE

    struct sockaddr_in address;
    size_t address_len = sizeof(address);
    memset(&address, 0, address_len);
    address.sin_len = address_len;
    address.sin_family = AF_INET;

    SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithAddress(NULL, (const struct sockaddr*)&address);

#endif

    if (reachabilityRef != NULL)
    {
        SCNetworkReachabilityFlags flags = 0;

        if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
        {
            BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
            BOOL connectionRequired = ((flags & kSCNetworkFlagsConnectionRequired) != 0);
            returnValue = (isReachable && !connectionRequired) ? YES : NO;
        }

        CFRelease(reachabilityRef);
    }

    return returnValue;

}

【讨论】:

  • 这应该是答案!谢谢!
  • 有人测试过吗?
  • sockaddrsockaddr_in 有什么区别,应该在 tvOS 上使用哪个?
【解决方案2】:

一种方法是:

// Check whether the user has internet
- (bool)hasInternet {
    NSURL *url = [[NSURL alloc] initWithString:@"http://www.google.com"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5.0];
    BOOL connectedToInternet = NO;
    if ([NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]) {
        connectedToInternet = YES;
    }
    //if (connectedToInternet)
        //NSLog(@"We Have Internet!");
    [request release];
    [url release];
    return connectedToInternet;
}

【讨论】:

  • 它正是我想要的。谢谢。
  • 这是一个糟糕的解决方案。您的应用程序将冻结,直到请求成功或失败。这可能会导致您的应用程序停止长达 60 秒,如果它们存在导致请求在达到超时之前不会失败的路由问题。您的用户不会欣赏这一点。即使成功,应用程序也可能会停止几秒钟,尤其是在连接速度较慢的情况下。
  • 但是如果你使用 NSOperation,或者 GCD 使用这种方法呢?我认为它可以正常工作,并且不会冻结 UI。
  • 在这样的固定 URL 上测试连接可达性不是一个好习惯。如果谷歌离线但客户端有互联网,你能说什么?此外,在您测试 HTTPS url 上的连接的许多情况下,此测试会失败。不赞成这个答案。
  • 这仍然适用于屏蔽 Google 的国家/地区吗?
【解决方案3】:

查看SCNetworkReachability 参考。这是一个 C API,因此它不像单个方法调用那样容易使用,但它可以很好地通知您的应用程序何时通过网络可以访问或无法访问特定地址。

大体上,您将使用SCNetworkReachabilityCreateWithAddressSCNetworkReachabilityCreateWithName 创建一个对象,然后使用SCNetworkReachabilityScheduleWithRunLoop 将其添加到运行循环中。当可达性被确定并且当它改变时,你提供的回调函数将被调用。您可以使用它来更新应用程序的状态。

Apple 提供了 an example app 来说明如何使用它(尽管它是为 iOS 设计的,而不是 Mac OS X)

【讨论】:

  • 非常感谢很有趣。但我需要它用于 MAC OS。我认为应该有更简单易用的东西。我想检查我是否连接到互联网 - 做某事。 Like (ifConnected) {//在这里做 }
  • 这在 Mac OS X 上可用(链接的文档来自 Mac OS X 库)。该示例恰好是为 iOS 编写的。没有系统提供的isConnected 方法。但是你可以使用它来编写你自己的isConnected 方法。
猜你喜欢
  • 2017-11-22
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多