如何在macOS上无数据消耗获取上传下载速度?求系统API方案
无需消耗流量获取macOS实时网速的系统API方案
1. Network 框架(推荐,适配macOS 10.14+)
苹果原生的Network框架提供了无额外流量消耗的网络统计能力,无需主动发起上传/下载请求就能获取实时流量数据:
- 通过
NWPathMonitor监听网络状态变化,同时借助NWInterface获取对应活跃接口的流量统计 - 核心调用:
NWInterface.statistics(completionHandler:),返回的NWInterface.Statistics结构体包含bytesReceived(累计接收字节)和bytesSent(累计发送字节)字段,通过计算两次采样的字节差与时间差的比值,即可得到实时上传/下载速度 - 示例代码片段:
import Network var lastReceived: UInt64 = 0 var lastSent: UInt64 = 0 var lastSampleTime = Date() let monitor = NWPathMonitor() monitor.pathUpdateHandler = { path in for interface in path.availableInterfaces where interface.type != .loopback { interface.statistics { stats, error in guard let stats = stats else { return } let currentTime = Date() let timeInterval = currentTime.timeIntervalSince(lastSampleTime) let downloadSpeed = Double(stats.bytesReceived - lastReceived) / timeInterval let uploadSpeed = Double(stats.bytesSent - lastSent) / timeInterval // 这里更新菜单栏图标展示的速度数据 lastReceived = stats.bytesReceived lastSent = stats.bytesSent lastSampleTime = currentTime } } } monitor.start(queue: DispatchQueue.global(qos: .background))
2. sysctl 系统调用(兼容低版本macOS)
通过BSD层的sysctl接口可直接读取系统内核维护的网络接口统计数据,无需依赖高层框架:
- 读取
CTL_NET->NET_RT_IFLIST节点,获取所有网络接口的原始统计信息 - 解析返回的
if_msghdr结构体,其中ifm_data字段包含ifi_ibytes(累计接收字节)和ifi_obytes(累计发送字节) - 示例代码片段(C/Obj-C):
#include <sys/sysctl.h> #include <net/if.h> #include <net/if_dl.h> uint64_t lastReceived = 0; uint64_t lastSent = 0; NSDate *lastSampleTime = [NSDate date]; size_t len = 0; sysctlbyname("net.inet.iflist", NULL, &len, NULL, 0); char *buf = malloc(len); sysctlbyname("net.inet.iflist", buf, &len, NULL, 0); struct if_msghdr *ifm = (struct if_msghdr *)buf; while ((char *)ifm < buf + len) { if (ifm->ifm_type == RTM_IFINFO) { struct if_data *ifd = &ifm->ifm_data; uint64_t currentReceived = ifd->ifi_ibytes; uint64_t currentSent = ifd->ifi_obytes; NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:lastSampleTime]; double downloadSpeed = (currentReceived - lastReceived) / interval; double uploadSpeed = (currentSent - lastSent) / interval; // 更新菜单栏数据 lastReceived = currentReceived; lastSent = currentSent; lastSampleTime = [NSDate date]; } ifm = (struct if_msghdr *)((char *)ifm + ifm->ifm_msglen); } free(buf);
3. System Configuration 框架(旧版兼容备选)
虽然该框架部分API已被标记为废弃,但仍可在macOS 10.13及以下版本中使用:
- 通过
SCNetworkInterfaceCopyAll获取所有网络接口,再调用SCNetworkInterfaceGetStatistics获取统计数据 - 从
SCNetworkInterfaceStatisticsRef中提取kSCNetworkInterfaceStatisticsReceivedBytes和kSCNetworkInterfaceStatisticsSentBytes字段计算速度
关键注意事项
- 所有方案都是读取系统累计流量数据,必须定期采样并计算差值才能得到实时速度,单次读取仅能获取累计值
- 需过滤掉本地回环接口(如
lo0),只统计活跃的外部网络接口(如en0、en1) - 这些API均无需额外隐私权限,属于系统常规统计接口,可直接调用
内容的提问来源于stack exchange,提问作者noobEinstien
相关产品推荐
相关产品推荐

