为了账号安全,请及时绑定邮箱和手机立即绑定

iPhone数据使用跟踪/监控

iPhone数据使用跟踪/监控

繁星点点滴滴 2019-06-20 10:53:52
iPhone数据使用跟踪/监控我已经搜索过这个话题,但是很少发现有帮助的细节。关于这些细节,我尝试编写如下代码。注:请将此帖子中分享的细节与其他帖子进行比较,然后再将其标记为重复,而不仅仅是主题。- (NSArray *)getDataCountersForType:(int)type {     BOOL success;     struct ifaddrs *addrs = nil;     const struct ifaddrs *cursor = nil;     const struct sockaddr_dl *dlAddr = nil;     const struct if_data *networkStatisc = nil;      int dataSent = 0;     int dataReceived = 0;     success = getifaddrs(&addrs) == 0;     if (success) {         cursor = addrs;         while (cursor != NULL) {             if (cursor->ifa_addr->sa_family == AF_LINK) {                 dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;                 networkStatisc = (const struct if_data *) cursor->ifa_data;                 if (type == WiFi) {                     dataSent += networkStatisc->ifi_opackets;                     dataReceived += networkStatisc->ifi_ipackets;                    }                 else if (type == WWAN) {                     dataSent += networkStatisc->ifi_obytes;                     dataReceived += networkStatisc->ifi_ibytes;                  }             }             cursor = cursor->ifa_next;         }         freeifaddrs(addrs);     }            return [NSArray arrayWithObjects:[NSNumber numberWithInt:dataSent], [NSNumber numberWithInt:dataReceived], nil];    }此代码收集iPhone设备的互联网使用信息(而不仅仅是我的应用程序)。现在,如果我通过WiFi或3G使用互联网,我只能在ifi_obytes(发送)和ifi_ibytes(收到)但我想我应该在ifi_opackets和ifi_ipackets.还想说,如果我连接到WiFi网络,但不使用互联网,我仍然可以获得增值ifi_obytes和ifi_ibytes.也许我在实现或理解上错了。需要有人帮我。编辑:而不是AF_LINK我试过AF_INET (sockaddr_in而不是sockaddr_dl)。这会使应用程序崩溃。
查看完整描述

3 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

问题是pdp_ip0是接口之一,所有pdpXXXWWAN接口专用于不同功能,语音信箱,一般网络接口。

我在苹果论坛上读到:操作系统不以进程为基础保存网络统计数据。因此,这个问题没有确切的解决办法。但是,您可以获取每个网络接口的网络统计信息。

总体而言en0是你的Wi-Fi界面和pdp_ip0是你的WWAN接口。

没有好的方式来获取信息无线/蜂窝网络数据,因为,特别的日期-时间!

数据统计(ifa_data->ifi_obytesifa_data->ifi_ibytes)是从以前的设备重新启动存储的。

我不知道为什么,但是ifi_opacketsifi_ipackets只为lo0(我认为它的主要接口)。

是。然后通过WiFi也不使用互联网if_iobytes值仍然存在,因为此方法提供网络字节交换,而不仅仅是Internet。

#include <net/if.h>#include <ifaddrs.h>static NSString *const DataCounterKeyWWANSent = @"WWANSent";
static NSString *const DataCounterKeyWWANReceived = @"WWANReceived";static NSString *const DataCounterKeyWiFiSent = @"WiFiSent";
static NSString *const DataCounterKeyWiFiReceived = @"WiFiReceived";NSDictionary *DataCounters(){
    struct ifaddrs *addrs;
    const struct ifaddrs *cursor;

    u_int32_t WiFiSent = 0;
    u_int32_t WiFiReceived = 0;
    u_int32_t WWANSent = 0;
    u_int32_t WWANReceived = 0;

    if (getifaddrs(&addrs) == 0)
    {
        cursor = addrs;
        while (cursor != NULL)
        {
            if (cursor->ifa_addr->sa_family == AF_LINK)
            {#ifdef DEBUG                const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
                if (ifa_data != NULL)
                {
                    NSLog(@"Interface name %s: sent %tu received %tu",cursor->ifa_name,ifa_data->ifi_obytes,ifa_data->ifi_ibytes);
                }#endif

                // name of interfaces:
                // en0 is WiFi
                // pdp_ip0 is WWAN
                NSString *name = @(cursor->ifa_name);
                if ([name hasPrefix:@"en"])
                {
                    const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
                    if (ifa_data != NULL)
                    {
                        WiFiSent += ifa_data->ifi_obytes;
                        WiFiReceived += ifa_data->ifi_ibytes;
                    }
                }

                if ([name hasPrefix:@"pdp_ip"])
                {
                    const struct if_data *ifa_data = (struct if_data *)cursor->ifa_data;
                    if (ifa_data != NULL)
                    {
                        WWANSent += ifa_data->ifi_obytes;
                        WWANReceived += ifa_data->ifi_ibytes;
                    }
                }
            }

            cursor = cursor->ifa_next;
        }

        freeifaddrs(addrs);
    }

    return @{DataCounterKeyWiFiSent : @(WiFiSent),
             DataCounterKeyWiFiReceived : @(WiFiReceived),
             DataCounterKeyWWANSent : @(WWANSent),
             DataCounterKeyWWANReceived : @(WWANReceived)};}

改进的复制/粘贴支持!


查看完整回答
反对 回复 2019-06-20
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

重要的是要了解这些计数器是提供的从设备上一次启动开始。

因此,为了有效地利用它们,您应该将设备的正常运行时间与每个示例一起使用(您可以使用mach_absolute_time()-见这,这个获得更多信息)

一旦您有了计数器示例+正常运行时间,您就可以有更好的启发式方法来使用数据.


查看完整回答
反对 回复 2019-06-20
?
喵喔喔

TA贡献1735条经验 获得超5个赞

要添加已接受的答案,重要的是要认识到接口显示的数据量溢出并重新启动于0之后4 GB,尤其是当您使用此代码计算两个读数之间的差异时。这是因为ifi_obytesifi_ibytesuint_32它们的最大值是4294967295.

此外,我建议使用unsigned ints表示包含发送和接收的数据的变量。正规化ints有一个无符号整数的最大值的一半,所以当添加ifi_obytes它可能会导致溢出。

unsigned int sent = 0;sent += networkStatisc->ifi_obytes;


查看完整回答
反对 回复 2019-06-20
  • 3 回答
  • 0 关注
  • 697 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信