iOS测量网速的三种方法

方法一:通过读取网卡信息

通过读取网卡数据来计算,读取上一秒的整体流量消耗 T1,然后读取当前的流量消耗 T2,那么 T2 - T1 其实可以表示为当前的一个网速情况。同时这个流量数据是可以区分蜂窝网络、Wi-Fi的,也可以区分哪些是上行流量,那些是下行流量。

#include <arpa/inet.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <net/if_dl.h>


struct ifaddrs *ifa_list = 0, *ifa;
    if (getifaddrs(&ifa_list) == -1) {
        return 0;
    }
    uint32_t iBytes = 0;
    uint32_t oBytes = 0;
    for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
        if (AF_LINK != ifa->ifa_addr->sa_family)
            continue;
        if (!(ifa->ifa_flags & IFF_UP) && !(ifa->ifa_flags & IFF_RUNNING))
            continue;
        if (ifa->ifa_data == 0)
            continue;
        /* Not a loopback device. */
        if (strncmp(ifa->ifa_name, "lo", 2)) {
            struct if_data *if_data = (struct if_data *)ifa->ifa_data;
            //下行
            iBytes += if_data->ifi_ibytes;
            //上行
            oBytes += if_data->ifi_obytes;
        }
    }
    freeifaddrs(ifa_list);

方法二:通过上传和下载数据包

通过上传和下载数据包,使用 TotalSize / TotalTime 来计算真实的上传和下载速率是多少。
下面是网上的一个3M的文件
http://dl.360safe.com/wifispeed/wifispeed.test //3M

#import <Foundation/Foundation.h>

typedef void (^LDSpeedBlock) (float speed);

@interface LDNetworkSpeedTool : NSObject

+ (instancetype)sharedInstance;

// 获取网速值,如果网速值为 0,则是获取失败
- (void)startWithURL:(NSURL*)url  speedblock:(LDSpeedBlock)speedBlock;

@end




#import "LDNetworkSpeedTool.h"

@interface LDNetworkSpeedTool() <NSURLSessionDownloadDelegate>

@property (nonatomic, assign) long long firstDownloadSize;
@property (nonatomic, assign) long long totalDownloadSize;
@property (nonatomic, assign) int totalDownTime;
@property (nonatomic, assign) NSTimeInterval startTimeStamp;
@property (nonatomic, assign) NSTimeInterval endTimeStamp;
@property (nonatomic, strong) LDSpeedBlock speedBlock;
@property (nonatomic, strong) NSURL *requestURL;

@end

@implementation LDNetworkSpeedTool

+ (instancetype)sharedInstance {
    static id instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (void)startWithURL:(NSURL*)url  speedblock:(LDSpeedBlock)speedBlock {
    self.requestURL = url;
    
    self.speedBlock = speedBlock;
    
    if (self.requestURL) {
        [self startMonitor];
    }
}

// 开始下载任务
- (void)startMonitor {
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
    NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:[NSURLRequest requestWithURL:self.requestURL]];
    
    [task resume];
}

// 结束下载任务,开始计算网速值
- (void)endMonitor {
    float value = (self.totalDownloadSize - self.firstDownloadSize) / (self.endTimeStamp - self.startTimeStamp);
    float speed = value / 1024 / 1024;
    self.speedBlock(speed);

}

#pragma mark - delegte
// 每次写入调用(会调用多次)
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    
    NSLog(@"value:%lld",totalBytesWritten);
    
    if (self.firstDownloadSize < 1) {
        self.firstDownloadSize = bytesWritten;
        // 开始计时:从第一次收到数据开始计时
        self.startTimeStamp = [[NSDate date] timeIntervalSince1970];
    }
    
    self.totalDownloadSize = totalBytesWritten;
}

// 下载完成调用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    self.endTimeStamp = [[NSDate date] timeIntervalSince1970];
    
    // 删除下载好的文件
    [[NSFileManager defaultManager] removeItemAtURL:location error:nil];
}

// 任务完成调用
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if (error) {
        
    } else {
        [self endMonitor];
    }
    // 如果发生错误则计算失效
    self.totalDownloadSize = 0;
    self.firstDownloadSize = 0;
}

三、通过ping的方式

这里推荐PPSPing
github地址:https://github.com/yangqian111/PPSPing
pod方式引入

pod 'PPSPing', '~> 0.3.0'

使用方式

@interface PPSAppDelegate()

@property (nonatomic, strong) PPSPingServices *service;

@end

@implementation PPSAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.service = [PPSPingServices serviceWithAddress:@"www.163.com"];
    [self.service startWithCallbackHandler:^(PPSPingSummary *pingItem, NSArray *pingItems) {
        NSLog(@"%@",pingItem);
    }];
    return YES;
}

@end

注意:在使用时,需要service存在强引用,不然不能够收到回调结果

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值