我在wifi网络范围内ping所有可用的IPS,如下所示:
for (int i=0; i < Range; i++) {
[SimplePingHelper ping:strIps[i]];
}
可以想象这个活动需要相当长的时间,因此我想在后台运行它。上面的代码段是我将在下面发布的更大方法的一部分。我已经完成了多个调试器会话,我注意到的一件事是,当我调用扫描方法时(见下文),samplePing(直接来自苹果)无法到达
static void HostResolveCallback(CFHostRef theHost,
CFHostInfoType typeInfo,
const CFStreamError *error,
void *info)
如果未达到此方法,则不会加载arp表,并且我的应用程序不再有效。
以下是我如何调用GCD:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0 ), ^{
[self scanWifi];
});
这是scanWifi方法:
-(void)scanWifi{
WifiInfo *wi = [[WifiInfo alloc] init];
NSString *phoneIp = [wi getIPAddress:true];
NSString *maxIp = [wi getBroadcastIp:phoneIp];
NSString *minIp = [wi getMinIp:phoneIp];
unsigned long ULmaxIp = [wi StrIp2UnsignedLong:maxIp];
unsigned long ULminIp = [wi StrIp2UnsignedLong:minIp];
ULmaxIp --;
ULminIp ++;
unsigned long iterateIp = ULminIp;
unsigned long Range = ULmaxIp - ULminIp;
NSString *strIps [Range];
for (int i = 0; i < Range; i++) {
strIps[i] = [wi unsignedInt2StrIp:iterateIp];
iterateIp ++;
}
for (int i=0; i < Range; i++) {
//I am using a simplePingHelper to handle management of the SamplePing
[SimplePingHelper ping:strIps[i]];
}
ip2mac *i2m = [[ip2mac alloc] init];
for (int i = 0; i < Range; i++) {
//convert the ip to a char string
char *chIp = (char *)[strIps[i] UTF8String];
//use the char string to look into arp table
NSString *mac = [[i2m Stip2mac:chIp]uppercaseString];
//this is the mac prefix I want
if([mac hasPrefix:@"60:CB:FB"]) {
//check device exists
if ([self deviceExist]) {
//update device that already exists in core data
[self updateToCoreData:@"AirScapeFan" :strIps[i] :mac :@"ssid"];
}else{
//add new device to core data
[self saveToCoreData:@"AirScapeFan" :strIps[i] :mac :@"ssid"];
}
//Method to call up all entries in core data and print them
[self printFromCoreData];
}
}
}
只是为了踢:这是我稍微修改过的SimplePingHelper代码:
//
// SimplePingHelper.m
// PingTester
//
// Created by Chris Hulbert on 18/01/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "SimplePingHelper.h"
@interface SimplePingHelper()
@property(nonatomic,retain) SimplePing* simplePing;
- (id)initWithAddress:(NSString*)address;
- (void)go;
@end
@implementation SimplePingHelper
@synthesize simplePing;
#pragma mark - Run it
// Pings the address, and calls the selector when done. Selector must take a NSnumber which is a bool for success
+ (void)ping:(NSString*)address {
// The helper retains itself through the timeout function
[[[SimplePingHelper alloc] initWithAddress:address] go];
}
#pragma mark - Init/dealloc
- (void)dealloc {
self.simplePing = nil;
}
- (id)initWithAddress:(NSString*)address {
if (self = [self init]) {
self.simplePing = [SimplePing simplePingWithHostName:address];
self.simplePing.delegate = self;
}
return self;
}
#pragma mark - Go
- (void)go {
[self.simplePing start];
[self performSelector:@selector(endTime) withObject:nil afterDelay:1]; // This timeout is what retains the ping helper
}
#pragma mark - Finishing and timing out
// Called on success or failure to clean up
- (void)killPing {
[self.simplePing stop]; // In case, higher up the call stack, this got called by the simpleping object itself
self.simplePing = nil;
}
- (void)successPing {
[self killPing];
}
- (void)failPing:(NSString*)reason {
[self killPing];
}
// Called 1s after ping start, to check if it timed out
- (void)endTime {
if (self.simplePing) { // If it hasn't already been killed, then it's timed out
[self failPing:@"timeout"];
}
}
#pragma mark - Pinger delegate
// When the pinger starts, send the ping immediately
- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address {
[self.simplePing sendPingWithData:nil];
}
- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error {
[self failPing:@"didFailWithError"];
}
- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet error:(NSError *)error {
// Eg they're not connected to any network
[self failPing:@"didFailToSendPacket"];
}
- (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet {
[self successPing];
}
@end