我搜索过这个主题,但发现很少有有用的细节。有了这些细节,我尝试编写一些代码如下。
注意:在将此帖子标记为重复之前,请将此帖子中共享的详细信息与其他帖子进行比较,而不仅仅是按主题。
- (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_obytes
和 ifi_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_obytes
和ifa_data->ifi_ibytes
)是从之前的设备重启中存储的。
我不知道为什么,但是 ifi_opackets
和 ifi_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/