如何快速扫描局域网内所有IP的某一个端口是否开启

一头头 2011-05-24 04:03:04
例如:

本机IP: 123.333.222.10

需要扫描 IP: 123.333.222.1:6610 - 123.333.222.224:6610 判断端口是否开启 或者说是否有server在监听这个端口

请问如何快速(1秒内)完成上面的224个执行(from 1 to 224)

我自己贴一段代码 可以用是可以用 但是太慢了
本来想用

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task(ipHead, tail, 6610)),
200, TimeUnit.MILLISECONDS);
executor.shutdown();

来提到效率的 但是好像没用 不知道是什么问题


runnable code:


import java.net.*;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.io.*;

public class JPortScanner1 {

public JPortScanner1(String IP, int port) {

}

public static void main(String[] args) throws IOException,
InterruptedException {

String ipHead;
int lastPoint;
String IP = InetAddress.getLocalHost().getHostAddress();

lastPoint = IP.lastIndexOf('.');

ipHead = IP.substring(0, ++lastPoint);

for (int tail = 234; tail < 255; tail++) {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task(ipHead, tail, 6610)),
200, TimeUnit.MILLISECONDS);
executor.shutdown();
}

}
}

class Task implements Callable<String> {
String ipHead;
int ipTail;
int port;

public Task(String ipHead, int ipTail, int port) {
this.ipHead = ipHead;
this.ipTail = ipTail;
this.port = port;
}

public String call() throws Exception {
Socket connect = new Socket();
connect.setSoTimeout(100);
try {

connect = new Socket(this.ipHead + ipTail, this.port);
connect.close();

System.out.println("Open port:" + this.ipHead + ipTail + " "
+ this.port);

} catch (UnknownHostException e) {
System.out.println("Unknown Port:" + this.ipHead + ipTail + " "
+ this.port);
} catch (IOException e) {
System.out.println("Unknown Port:" + this.ipHead + ipTail + " "
+ this.port);
}

System.out.println("Finished!");
return null;

}
}


...全文
2119 49 打赏 收藏 转发到动态 举报
写回复
用AI写文章
49 条回复
切换为时间正序
请发表友善的回复…
发表回复
敌敌畏耶 2013-03-22
  • 打赏
  • 举报
回复
如果 把这个运用到C# 中 怎么搞?
alinchuan 2011-06-01
  • 打赏
  • 举报
回复
表示关注,如果csdn里有这样的气氛,这样的好帖就好了!
ljf_ljf 2011-05-31
  • 打赏
  • 举报
回复
协议简单速度肯定快,容错性低。
协议复杂速度肯定慢,容错性高。
一头头 2011-05-31
  • 打赏
  • 举报
回复
扫描端口是手段 检测到同一network内的机器是目的

所以把所有机器装上broadcast就可以了 代码就不放了 简单得很

TCPIP确实做不到 快速的扫描
BearKin 2011-05-30
  • 打赏
  • 举报
回复
..明明是两只胖熊嘛...

注释上已经写明了一些参数的作用 比如你可以通过设置重试次数以及等待时间把程序的执行时间限制死 别的我就没啥办法了
一头头 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 bearkin 的回复:]

。。。。

大概意思..
[/Quote]

谢谢哇 我刚刚试了下 不错哇 不过我希望可以在2秒之内知晓整个局域网1-254地址内的所有被开启的服务器。这个服务器开启就占用6610端口。

最近比较忙得跟狗一样 过几天写完了把代码贴出来
一头头 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 jia20003 的回复:]

传统的TCP链接扫描是最傻一种, 而且消耗CPU资源,相应的时间还跟网络带宽资源有一定的关系。
Java没有提供基于IP层的编程接口,无法实现TCP半开/半闭扫描,前面有提到Nmap

Nmap提供了非常全的TCP扫描方式,基础指纹栈识别技术,通过TCP扫描来识别操作系统,进而发现
系统漏洞,为下一步入侵系统探路。
[/Quote]

我是看过 2个问题
1. 语言的问题 我需要跨平台解决方案 NMAP不是java搞的
2. NMAP有很多的依赖 对于一个商业软件来说 这种依赖很要命
BearKin 2011-05-30
  • 打赏
  • 举报
回复
package net;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class JPortScannerByNIO {
public static void main(String[] args) throws IOException {
int port = 80;
int retry = 10;// 重试次数
String ip = InetAddress.getLocalHost().getHostAddress();
String ipHead = ip.substring(0, ip.lastIndexOf('.') + 1);
Selector selector = Selector.open();

for (int tail = 60; tail < 65; tail++) {
SocketChannel channel = SocketChannel.open();

SocketAddress address = new InetSocketAddress(ipHead + tail, port);

channel.configureBlocking(false);
channel.connect(address);
channel.register(selector, SelectionKey.OP_CONNECT, address);// 这里你也可以用输入或者输出
}
while (retry-- > 0) {
// selector.select(1000 * 5);这里可以设置超时时间
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();

for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext();) {
SelectionKey key = it.next();
it.remove();

if (key.isConnectable()) {
System.err.println(key.attachment());
key.cancel();
}
}
}
}
}


大概意思..
BearKin 2011-05-30
  • 打赏
  • 举报
回复
你的代码可以不用线程 还有优化的余地 比如用NIO去做 代码回头放送....
BearKin 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 coldanimal 的回复:]
我在想另外一种思路 比如广播?
[/Quote]

组播通过UDP试验 无法查到TCP端口占用信息

占个位置 表示关注 OYE..
ying246437 2011-05-30
  • 打赏
  • 举报
回复
对于初学者来说,像看天书一样 呵呵
gloomyfish 2011-05-30
  • 打赏
  • 举报
回复
传统的TCP链接扫描是最傻一种, 而且消耗CPU资源,相应的时间还跟网络带宽资源有一定的关系。
Java没有提供基于IP层的编程接口,无法实现TCP半开/半闭扫描,前面有提到Nmap

Nmap提供了非常全的TCP扫描方式,基础指纹栈识别技术,通过TCP扫描来识别操作系统,进而发现
系统漏洞,为下一步入侵系统探路。

一头头 2011-05-30
  • 打赏
  • 举报
回复
另外 TCPIP也是可以的 唯一的问题就是timeout的问题

扫描的时间太TM长了

34楼很有道理
一头头 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 ljf_ljf 的回复:]

其实应该和程序编写无关。楼主你现在是想要用UDP协议来测试还是TCP协议来测试呢?
若你要用UDP基本可以群发给各个主机去测试;但在目的机器上必须要有客户端程序进行接收和回复信息。
但你用TCP协议不可能快的;因为TCP通信协议就会复杂以及一些安全考虑(半连接处理和限制)。优点就是不需要在目的机器上安装测试程序。

若你觉得多线程去发送信息的效果不理想,TCP协议群发效果也不会有太大提升……
[/Quote]

是的 应该是UDP 用broadcast来实现

我写完把代码放出来 再结贴。
ljf_ljf 2011-05-26
  • 打赏
  • 举报
回复
其实应该和程序编写无关。楼主你现在是想要用UDP协议来测试还是TCP协议来测试呢?
若你要用UDP基本可以群发给各个主机去测试;但在目的机器上必须要有客户端程序进行接收和回复信息。
但你用TCP协议不可能快的;因为TCP通信协议就会复杂以及一些安全考虑(半连接处理和限制)。优点就是不需要在目的机器上安装测试程序。

若你觉得多线程去发送信息的效果不理想,TCP协议群发效果也不会有太大提升。
hundlom 2011-05-26
  • 打赏
  • 举报
回复
请参考linux的Nmap源代码
oO临时工Oo 2011-05-26
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 afer198215 的回复:]
引用 28 楼 trocp 的回复:
实际你可以把255分成5次,50个线程池,等一组全部运行完成了再下一组。50个线程一起应该不算多吧。我觉得100个都不算多。

50个线程没什么问题,但是50个tcp连接占用的资源就比较大了。
[/Quote]

你打开一个ie,多打开几个不同的站点,可能就是20几个连接,QQ也不会少,要是P2P这种下载工具,就更不用说了。所以我觉得50个连接也不会太大。到少我所引用的代码在我这里测试很顺畅。当然我的局域网机子比较少。

还有一个问题,一个局域网不可能每个机子都开启你所指定的端口,所以连接都不会建立,也就没有更多资源问题了。只是尝试建立连接的时间等待消耗。
想喝咖啡的貓 2011-05-26
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 trocp 的回复:]
实际你可以把255分成5次,50个线程池,等一组全部运行完成了再下一组。50个线程一起应该不算多吧。我觉得100个都不算多。
[/Quote]
50个线程没什么问题,但是50个tcp连接占用的资源就比较大了。
KPRF2009 2011-05-26
  • 打赏
  • 举报
回复
mark 标记了。。。我是来学习的、、、
lxbccsu 2011-05-25
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 coldanimal 的回复:]
线程池一下子搞255个线程本来就是有问题的 虽然CPU是没有问题
[/Quote]
Executors.newCachedThreadPool();创建的实际是个ThreadPoolExecutor,这里我可以肯定的说不会有255个线程;
其实你可以直接的new ThreadPoolExecutor来指定最大线程数:
ThreadPoolExecutor(4, 8, 1000, TimeUnit.MILLISECONDS, new BlockingQueue<Runnable>());

至于说能不能上网,那是网络管理设置的问题了;

再说现在测试的结果也不保证下次测试是一样的,谁知道接下来会发生什么事情;
也许服务器本身就是个单线程响应 或 现在很忙无法响应...
加载更多回复(28)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧