Я просмотрел несколько вопросов по SO об AsyncSocket, но ничего не нажал. Я чувствую, что то, что я пытаюсь сделать, довольно просто, так что это будет ладонь... Я пробовал версию без GCD, но это тоже не приносит удовольствия.
Мне нужно иметь возможность сканировать ряд хостов для определенного открытого TCP-порта. К сожалению, у меня нет контроля над кодом сервера, чтобы он объявлял себя с помощью Bonjour. Итак, я приступаю к сканированию грубой силы и просто пытаюсь подключиться к этому одному порту - если я получаю «Отказ в подключении», то я знаю, что нужно двигаться дальше ...
Все это привело меня к AsyncSocket, который я считаю подходящим инструментом для работы. Используя примеры автора, у меня есть базовый рабочий пример, но не совсем. Как и его образцы, я просто использую основную очередь для простоты. Дело в том, что это похоже на дерьмовую стрельбу относительно того, вызывается ли метод делегата. Иногда socketDidDisconnect: срабатывает, иногда нет. В данном конкретном случае я знаю, что порт 5002 открыт на 192.168.1.7. Однако, когда он достигает этого элемента в массиве, didConnectToHost не срабатывает. Однако, если я удалю из списка IP-адресов все, кроме .7, то didConnectToHost сработает. Я подозреваю, что вызов connectToHost: в таком тесном цикле является проблемой, но я не могу это доказать. Если кто-то знает более простой способ сделать это, я открыт для него. Удивительно, но на эту тему не так много.
#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 : @"");
}