【问题标题】:Reachability returns False for Cellular network when both Wi-Fi and Cellular is ON当 Wi-Fi 和蜂窝网络都打开时,蜂窝网络的可达性返回 False
【发布时间】:2012-04-12 23:59:46
【问题描述】:

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

现在我发现,当我同时打开蜂窝网络和 WIFI 时,我的蜂窝网络检查显示为 FALSE,而我的 WIFI 检查显示为 TRUE。

我已尝试为此修改 NetworkStatus 返回值。但没有成功。

谁能帮我解决这个问题???

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

谁能帮我理解以下几点:

  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;
    }
    

以及如何更改以下代码以仅获取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 中我得到了 TRUE,只有在蜂窝网络中我得到了 FALSE。

+ (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;
}

【问题讨论】:

  • 我认为这是一个全球性问题。因为当我使用“whatsapp”并且应用程序上的 wifi 和蜂窝数据都突然停止发送消息时,就像没有网络一样!
  • @Malek_Jundi :所以你的意思是没有解决办法???或者有没有其他方法?请看我编辑的问题...
  • 请在下面查看我的答案。

标签: iphone objective-c ios ios5 reachability


【解决方案1】:

行:

**BOOL** retVal = NotReachable;

无效。这应该是:

**NetworkStatus** retVal = NotReachable;

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

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

【讨论】:

    【解决方案2】:

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

    您获得的唯一信息是您的应用是否可以连接到远程服务器。你没有得到任何关于它正在使用哪个连接的信息。

    【讨论】:

    • 这是正确的,但根据 NetworkStatus 标志我可以知道它是 WIFI 还是 WWAN。所以我只想要那个......
    • 是的,WIFI 是 LOCAL WIFI(即私有 IP 地址范围内的本地网络)。 WWAN 是广域网 - “互联网”。您的蜂窝网络将无法访问您的本地网络,因为它是通过移动运营商的网络连接的。
    • 感谢尼克的回复,但你能清楚你想得出什么结论吗?我也编辑了我的问题,所以请看一下...
    • 我的意思是,你能得到的唯一信息是你是连接到本地网络(WIFI 表示本地 wifi 网络)还是互联网(WWAN 表示无线广域网)。您不知道设备使用哪种传输服务连接到互联网,您只是被告知您已连接到互联网。您可能正在使用蜂窝网络或无线网络,但您的应用不会知道(也不应该在意)。
    • 您对传输服务的看法是正确的。但我只是希望当我检查蜂窝网络的可用性时它应该返回 TRUE,不关心它是否用于传输......
    【解决方案3】:

    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”是来自 Reachability 类的实例变量。

    希望这会有所帮助。

    【讨论】:

    • 我认为您对第二个问题的解释有误。我想要的是当我的应用程序启动时,我会检查可到达性 WIFI 和 CELLULAR。虽然我都打开了,但在 CELLULAR 的情况下我会得到 FALSE。你能告诉我上面的代码对我的情况有什么帮助吗???
    • 对不起,我不了解您的需求.. 我只是与您分享我的代码,因为我认为它可能对您有所帮助。但我不觉得我应该投反对票!您的评论很公平..再次为错误的答案道歉。
    • 对不起,我没有投反对票。我也不能给你投票,因为我还没有找到正确的答案。
    • 我的问题也很简单,当我检查蜂窝网络和 Wifi ON 的可达性时,在这两种情况下我都应该得到 TRUE 值......
    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多