同一时间ping多个IP地址

Apple本身有一个专门ping IP的工具类,叫做SimplePing

/*! An object wrapper around the low-level BSD Sockets ping function.
 *  \details To use the class create an instance, set the delegate and call `-start` 
 *      to start the instance on the current run loop.  If things go well you'll soon get the 
 *      `-simplePing:didStartWithAddress:` delegate callback.  From there you can can call 
 *      `-sendPingWithData:` to send a ping and you'll receive the 
 *      `-simplePing:didReceivePingResponsePacket:sequenceNumber:` and 
 *      `-simplePing:didReceiveUnexpectedPacket:` delegate callbacks as ICMP packets arrive.
 *
 *      The class can be used from any thread but the use of any single instance must be 
 *      confined to a specific thread and that thread must run its run loop.
 */

@interface SimplePing : NSObject

关于SimplePing的源码解读网上还是挺多的,感兴趣的小伙伴可以看一看iOS ping - SimplePing 源码解读,然后自己跑一下流程,不想看的同学可以直接看总结

  • 解析hostname成IP地址
  • 发包
  • 收包

但是SimplePing并没有告诉我们从发包到收包具体花了多久,所以需要我们自己去实现,此外,我们可能还需要同时去ping多个IP地址,这也是比较常见的需求之一。
基于以上两点需求,我在SimplePing的基础上封装了NENPingManager

内部实现原理如下:
获取IP地址数组后,先遍历派发任务,创建NENSinglePinger,默认会ping3次,NENSinglePinger会记录3次ping的结果,并取平均值

        for (NSString *address in addressList) {
            
            NENSinglePinger *singlePinger = [NENSinglePinger startWithHostName:address count:3 pingCallBack:^(NENPingItem *pingitem) {
                // 省略
                ...
            }];
            [singlePingerArray addObject:singlePinger];
        }

NENSinglePinger是对SimplePing的封装,相当于一个单体ping工具,内部实现了SimplePing的代理,在创建的时候,会启动SimplePing- (void)start方法,如果一切正常,会调用- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address代理方法,在这个方法中会创建一个定时器,每隔0.4s会去发一次包,从发包开始会开始计时,记录每次发包的时间,如果在1s钟之内没有收到包,就调用- (void)timeOut方法,按照延迟处理,延迟时间默认为1s,如果收到了包,就记录数据,并和开始的发包时间比较,并把数据回调给
NENPingManager,当收到3次操作拉满的时候,就是收到包和timeout的次数到达3次的时候,就操作终止,清楚掉定时器和其他的一些缓存数据。

tips: 如果没有效果,请确保NENSinglePinger是被强引用的,如果你用一个临时变量,可能还没开始请求就都被释放了。

Demo地址
喜欢的话就点个赞吧

你可能感兴趣的:(同一时间ping多个IP地址)