我已经研究了关于 AsyncSocket 的一些关于 SO 的问题,但没有点击任何内容。我觉得我正在尝试做的事情相当简单,所以它会是面对面的......我已经尝试过非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 : @"");
}