当Wi-Fi和Cellular均为ON时,可达性为蜂窝网络返回False

时间:2012-03-29 10:36:38

标签: iphone objective-c ios ios5 reachability

我正在使用Apple's Reachability code来确定是否存在互联网连接。

现在我发现当我保持Both Cellular和WIFI ON时,我对Cellular的检查显示为FALSE,我的WIFI检查显示为TRUE。

我已经尝试修改NetworkStatus的返回值..但没有成功。

任何人都可以帮我解决这个问题???

我想要的是当两个网络都打开时,我的可达性应该对两者都显示为真。

任何人都可以帮助我理解以下几点:

  1. SCNetworkReachabilityGetFlags(reachabilityRef, &flags)将会做什么?

  2. 如何仅检查以下代码中的networkStatusForFlags

    - (NetworkStatus) currentReachabilityStatus
    {
    NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
    NetworkStatus retVal = NotReachable;
    SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
    {
        if(localWiFiRef)
        {
            retVal = [self localWiFiStatusForFlags: flags];
        }
        else
        {
            retVal = [self networkStatusForFlags: flags];
        }
    }
    return retVal;
    }
    
  3. 另外如何更改以下代码以仅获取NetworkStatusForFlags

    - (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags
    {
        if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
        {
            // if target host is not reachable
            return NotReachable;
        }
    
        BOOL retVal = NotReachable;
    
        if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
        {
            // if target host is reachable and no connection is required
            //  then we'll assume (for now) that your on Wi-Fi
            retVal = ReachableViaWiFi;
        }
    
    
        if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
             (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
        {
            // ... and the connection is on-demand (or on-traffic) if the
            //     calling application is using the CFSocketStream or higher APIs
    
            if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
            {
                // ... and no [user] intervention is needed
                retVal = ReachableViaWiFi;
            }
        }
    
        if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
        {
            // ... but WWAN connections are OK if the calling application
            //     is using the CFNetwork (CFSocketStream?) APIs.
            retVal = ReachableViaWWAN;
        }
        return retVal;
    }
    

    编辑:

    我使用的主机名为www.apple.com,并尝试了http://www.apple.com。但是在WIFI中我得到了真正的,只有在蜂窝网络中我才变得虚假。

    + (MTPReachability*) reachabilityWithHostName: (NSString*) hostName;
    {
        MTPReachability* retVal = NULL;
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
        if(reachability!= NULL)
        {
            retVal= [[[self alloc] init] autorelease];
            if(retVal!= NULL)
            {
                retVal->reachabilityRef = reachability;
                retVal->localWiFiRef = NO;
            }
        }
        return retVal;
    }
    

3 个答案:

答案 0 :(得分:2)

该行:

**BOOL** retVal = NotReachable;

无效。这应该是:

**NetworkStatus** retVal = NotReachable;

在我们的例子中,它帮助在retVal中设置了正确的值(即ReachableViaWWAN)。

否则,即使您输入最后一个“if”,您也会获得ReachableViaWiFi,因为它被转换为BOOL。

答案 1 :(得分:0)

WIFI仅指示您是否在本地WiFi连接上(在私有IP地址范围内),而不是您在设备上使用wifi连接。

您获得的唯一信息是您的应用是否可以连接到远程服务器。您无法获得有关其使用的连接的任何信息。

答案 2 :(得分:-1)

1. SCNetworkReachabilityGetFlags(reachabilityRef, &flags)将确定使用当前网络配置是否可以访问给定目标。

2.请检查我的代码,通过它我检查网络的可达性

+ (BOOL) connectedToNetwork
{
    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;

    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);

    if (!didRetrieveFlags)
    {
        return NO;
    }

    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    return (isReachable && !needsConnection) ? YES : NO;
}

- (void) checkNetworkStatus:(NSNotification *)notice
{
    // called after network status changes

    NetworkStatus netStatus = [internetReach currentReachabilityStatus];
    switch (netStatus)
    {
        case NotReachable:
        {
            if([reachabilityDelegate respondsToSelector:@selector(internetConnectionLost)])
                [reachabilityDelegate internetConnectionLost];
            break;

        }
        case ReachableViaWiFi:
        case ReachableViaWWAN:
        {
            if([reachabilityDelegate respondsToSelector:@selector(internetConnectionRestored)] && [GlobalObjects connectedToNetwork])
                [reachabilityDelegate internetConnectionRestored];
            break;

        }
    }
}

注意“reachabilityDelegate”是一个委托我定义它以获取其他类的网络类..而“internetReach”是来自可达性类的实例变量。

希望这会有所帮助。