0我已经在关于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 : @"");
}
答案 0 :(得分:1)
我尝试了类似的东西,我首先找到了自己的IP,然后修改它以显示整个子网范围。我得到的东西像&#34; 192.168.10。&#34;然后我做了
- (void)startScan:(NSString *)ipRange
{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
NSError *error = nil;
for (int i = 1; i < 255; i++) {
NSString *scanHostIP = [NSString stringWithFormat:@"%@%d", ipRange, i];
[asyncSocket connectToHost:scanHostIP onPort:PORT error:&error];
}
//connect to an IP that listens on the certain port
[asyncSocket connectToHost:@"192.168.10.162" onPort:PORT error:&error];
}
当我尝试在循环中连接到162时,委托方法永远不会被调用。但是,当我只连接到那个特定的IP时,它突然被调用。 有趣的是,当我第一次运行循环然后尝试连接到特定主机时,委托方法不会被调用。
我尝试连接有没有超时但没有诀窍。
我检查了connectToHost方法,它总是返回一些东西。即使我尝试连接到2个IP,它也不会触发委托方法。
总结我的经验:循环似乎以某种方式阻止了委托方法。我怀疑它只是意味着连接到一个地址?那么它将是用于扫描子网的错误工具。
修改强> 我找到了一个很好的解决方为了扫描整个网络,我开始使用以下代码:
-(void)startScan
{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
NSError *error = nil;
NSString *scanHostIP = [NSString stringWithFormat:@"%@%d", ipRange, count];
[asyncSocket connectToHost:scanHostIP onPort:PORT withTimeout:0.01 error:&error];
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
NSError *error;
if(count < 254)
{
count++;
NSString *scanHostIP = [NSString stringWithFormat:@"%@%d", ipRange, count];
[asyncSocket connectToHost:scanHostIP onPort:PORT withTimeout:0.01 error:&error];
}
}
诀窍是等待套接字超时,然后启动新连接。这样,您就可以在可容忍的时间间隔内扫描整个网络。
希望这可以帮助你或其他人。