iPhone 数据使用跟踪/监控

标签 iphone ios sockets

我搜索过这个主题,但发现很少有有用的细节。有了这些细节,我尝试编写一些代码如下。

注意:在将此帖子标记为重复之前,请将此帖子中共享的详细信息与其他帖子进行比较,而不仅仅是按主题。

- (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 中使用 WiFi和 ifi_ipackets .

还想补充一点,如果我连接到 WiFi 网络,但不使用互联网,我仍然会获得附加值到 ifi_obytesifi_ibytes .

可能是我在执行或理解上有误。需要有人帮助我。


编辑:代替AF_LINK我试过 AF_INET ( sockaddr_in 而不是 sockaddr_dl )。这会使应用程序崩溃。

最佳答案

pdp_ip0 是接口(interface)之一,所有pdpXXX 都是WWAN 接口(interface),专用于不同的功能,语音邮件,通用网络接口(interface)。

我在 Apple 论坛上读到: 操作系统不会逐个进程地保留网络统计信息。因此,这个问题没有确切的解决方案。但是,您可以获得每个网络接口(interface)的网络统计信息。

一般来说,en0 是您的Wi-Fi 接口(interface),pdp_ip0 是您的WWAN 接口(interface)。

没有很好的方法来获取信息 wifi/蜂窝网络数据,因为,特定的日期时间!

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

我不知道为什么,但是 ifi_opacketsifi_ipackets 只为 lo0 显示(我认为它的主要界面)。

是的。然后设备通过 WiFi 连接并且不使用互联网 if_iobytes 值仍然存在,因为此方法提供网络字节交换而不仅仅是互联网。

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

改进了复制/粘贴支持!

关于iPhone 数据使用跟踪/监控,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7946699/

相关文章:

iOS:如何写入项目中特定目录的文件?

ios - 无法使用类型为 'indexOf' 的参数列表调用 '(ChecklistItem)'

ios - 增加 dismissViewControllerAnimated() 的持续时间

c - C中的套接字编程 - 让浏览器丢弃已发送的消息

java - 如何读取socket中的大数据并写入socketchannel

iphone - 如何取消使用 AudioServicesPlaySystemSound 启动的播放声音?

ios - 如何保护 NSUserDefaults 上的整数数据免遭黑客攻击?

ios - 几天后正在测试的 iPhone 应用程序崩溃

ios - UIAlertController 作为跨 View Controller 访问的通用函数

c# - 好的UDP中继服务器设计