Sah*_*nna 135 sockets iphone ios
我搜索了这个主题,但发现很少有帮助的细节.有了这些细节,我试着按如下方式编写一些代码.
注意:请将此帖中分享的详细信息与其他帖子进行比较,然后再将其标记为DUPLICATE,而不仅仅是主题.
- (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];
}
Run Code Online (Sandbox Code Playgroud)
此代码收集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
).这会使应用程序崩溃.
use*_*705 173
问题是pdp_ip0
接口之一,所有接口pdpXXX
都是WWAN
专用于不同功能,语音邮件,通用网络接口.
我在Apple论坛中读到:操作系统不会逐个进行网络统计.因此,这个问题没有确切的解决方案.但是,您可以获取每个网络接口的网络统计信息.
通常en0
是您的Wi-Fi
界面,pdp_ip0
是您的WWAN
界面.
因为特定的日期时间没有获得信息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)};
}
Run Code Online (Sandbox Code Playgroud)
改进的复制/粘贴支持!
Jim*_*109 12
要添加到接受的答案,重要的是要意识到接口显示的数据量会溢出并在0
每次之后重新启动4 GB
,尤其是如果您使用此代码来计算两个读数之间的差异.这是因为ifi_obytes
和ifi_ibytes
是uint_32
和他们的最大值为4294967295
.
另外,我建议unsigned int
对包含发送和接收数据的变量使用s.常规int
s具有无符号整数的最大值的一半,因此在添加时ifi_obytes
,可能会导致溢出.
unsigned int sent = 0;
sent += networkStatisc->ifi_obytes;
Run Code Online (Sandbox Code Playgroud)
已接受答案的快速版本。我还将代码分解成更小的单元。
struct DataUsageInfo {
var wifiReceived: UInt32 = 0
var wifiSent: UInt32 = 0
var wirelessWanDataReceived: UInt32 = 0
var wirelessWanDataSent: UInt32 = 0
mutating func updateInfoByAdding(info: DataUsageInfo) {
wifiSent += info.wifiSent
wifiReceived += info.wifiReceived
wirelessWanDataSent += info.wirelessWanDataSent
wirelessWanDataReceived += info.wirelessWanDataReceived
}
}
class DataUsage {
private static let wwanInterfacePrefix = "pdp_ip"
private static let wifiInterfacePrefix = "en"
class func getDataUsage() -> DataUsageInfo {
var interfaceAddresses: UnsafeMutablePointer<ifaddrs> = nil
var dataUsageInfo = DataUsageInfo()
guard getifaddrs(&interfaceAddresses) == 0 else { return dataUsageInfo }
var pointer = interfaceAddresses
while pointer != nil {
guard let info = getDataUsageInfo(from: pointer) else {
pointer = pointer.memory.ifa_next
continue
}
dataUsageInfo.updateInfoByAdding(info)
pointer = pointer.memory.ifa_next
}
freeifaddrs(interfaceAddresses)
return dataUsageInfo
}
private class func getDataUsageInfo(from infoPointer: UnsafeMutablePointer<ifaddrs>) -> DataUsageInfo? {
let pointer = infoPointer
let name: String! = String.fromCString(infoPointer.memory.ifa_name)
let addr = pointer.memory.ifa_addr.memory
guard addr.sa_family == UInt8(AF_LINK) else { return nil }
return dataUsageInfo(from: pointer, name: name)
}
private class func dataUsageInfo(from pointer: UnsafeMutablePointer<ifaddrs>, name: String) -> DataUsageInfo {
var networkData: UnsafeMutablePointer<if_data> = nil
var dataUsageInfo = DataUsageInfo()
if name.hasPrefix(wifiInterfacePrefix) {
networkData = unsafeBitCast(pointer.memory.ifa_data, UnsafeMutablePointer<if_data>.self)
dataUsageInfo.wifiSent += networkData.memory.ifi_obytes
dataUsageInfo.wifiReceived += networkData.memory.ifi_ibytes
} else if name.hasPrefix(wwanInterfacePrefix) {
networkData = unsafeBitCast(pointer.memory.ifa_data, UnsafeMutablePointer<if_data>.self)
dataUsageInfo.wirelessWanDataSent += networkData.memory.ifi_obytes
dataUsageInfo.wirelessWanDataReceived += networkData.memory.ifi_ibytes
}
return dataUsageInfo
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
53049 次 |
最近记录: |