I've dug around on a few questions on SO about AsyncSocket, but nothing's clicked. I feel what I'm trying to do is fairly simple, so it'll be face-palm... I have tried the non-GCD version, but no joy there either.
I need to be able to scan a range of hosts for a specific open TCP port. Unfortunately, I don't have control of the server code to have it announce itself using Bonjour. So, I'm down to brute force scanning and just attempting to connect on that one port -- if I get 'Connection refused', then I know to move on...
All this led me to AsyncSocket, which I think is the right tool for the job. Using the author's examples, I've got a basic working example, but not quite. Like his samples, I'm just using the main queue for simplicity. The thing is, it seems to be a crap shoot as to whether or not the delegate method get called. Sometimes the socketDidDisconnect: fires, sometimes not. In this particular case, I know that port 5002 is open on 192.168.1.7. When it gets to that element in the array, though, the didConnectToHost doesn't fire. However, if I remove everything but .7 from the list of IPs, then didConnectToHost does fire. I'm suspicious that calling connectToHost: in such a tight loop is an issue, but I can't prove it. If someone knows a simpler way to accomplish this, I'm open to it. Surprisingly, there's not a lot on this topic.
#import "GCDAsyncSocket.h"
#define PORT 5002
@implementation ViewController
{
GCDAsyncSocket *asyncSocket;
NSMutableArray *availableHosts;
}
- (IBAction)startScan
{
NSArray *ipAddressList = @[@"192.168.1.1",@"192.168.1.2",@"192.168.1.3",@"192.168.1.4",@"192.168.1.5",@"192.168.1.6",@"192.168.1.7"];
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
NSError *error = nil;
for (int i = 1; i < ipAddressList.count; i++) {
NSString *scanHostIP = ipAddressList[i];
[asyncSocket connectToHost:scanHostIP onPort:PORT withTimeout:1 error:&error];
}
}
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(@"Found open port %d on %@", port, host);
[availableBeds addObject:host];
[sock setDelegate:nil];
[sock disconnect];
[sock setDelegate:self];
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
NSLog(@"Disconnected: %@", err ? err : @"");
}