如何快速扫描局域网内所有IP的某一个端口是否开启
例如:
本机IP: 123.333.222.10
需要扫描 IP: 123.333.222.1:6610 - 123.333.222.224:6610 判断端口是否开启 或者说是否有server在监听这个端口
请问如何快速(1秒内)完成上面的224个执行(from 1 to 224)
我自己贴一段代码 可以用是可以用 但是太慢了
本来想用
- Java code
ExecutorService executor = Executors.newSingleThreadExecutor();executor.invokeAll(Arrays.asList(new Task(ipHead, tail, 6610)),200, TimeUnit.MILLISECONDS);executor.shutdown();
来提到效率的 但是好像没用 不知道是什么问题
runnable code:
- Java 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; }}[解决办法]
不动手无说服力(并不说我是个高手,只是想说怎么这么多人不去思考动手呢)
我测试的一个示例也就200多微妙(双核CPU):
- Java code
import java.io.IOException;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.Socket;import java.net.UnknownHostException;import java.util.Collection;import java.util.LinkedList;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class JPortScanner1 { public static void main(String[] args) throws InterruptedException, UnknownHostException { String ipHead; int lastPoint; String IP = InetAddress.getLocalHost().getHostAddress(); lastPoint = IP.lastIndexOf('.'); ipHead = IP.substring(0, ++lastPoint); ExecutorService executor = Executors.newCachedThreadPool(); Collection<Callable<String>> list = new LinkedList<Callable<String>>(); long start = System.currentTimeMillis(); for (int tail = 1; tail < 255; tail++) { list.add(new Task(ipHead, tail, 8081)); } executor.invokeAll(list); executor.shutdown(); long end = System.currentTimeMillis(); System.out.println("All time: " + (end - start) + " milliseconds"); }}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; System.out.println(ipHead + ipTail + ":" + port); } public String call(){ Socket connect = new Socket(); try { connect.connect(new InetSocketAddress(ipHead + ipTail, port), 100); while(true){ if(connect.isConnected()){ //System.out.println(ipHead + ipTail + ":" + port + " success"); break; } } connect.close(); } catch (IOException e) { //System.out.println(ipHead + ipTail + ":" + port + " failure"); } return null; }}
[解决办法]
大哥,你的线程池怎么放到循环里面去了???
[解决办法]
[解决办法]
[解决办法]
其实应该和程序编写无关。楼主你现在是想要用UDP协议来测试还是TCP协议来测试呢?
若你要用UDP基本可以群发给各个主机去测试;但在目的机器上必须要有客户端程序进行接收和回复信息。
但你用TCP协议不可能快的;因为TCP通信协议就会复杂以及一些安全考虑(半连接处理和限制)。优点就是不需要在目的机器上安装测试程序。
若你觉得多线程去发送信息的效果不理想,TCP协议群发效果也不会有太大提升。
[解决办法]
传统的TCP链接扫描是最傻一种, 而且消耗CPU资源,相应的时间还跟网络带宽资源有一定的关系。
Java没有提供基于IP层的编程接口,无法实现TCP半开/半闭扫描,前面有提到Nmap
Nmap提供了非常全的TCP扫描方式,基础指纹栈识别技术,通过TCP扫描来识别操作系统,进而发现
系统漏洞,为下一步入侵系统探路。
[解决办法]
- Java code
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(); } } } }}
[解决办法]
..明明是两只胖熊嘛...
注释上已经写明了一些参数的作用 比如你可以通过设置重试次数以及等待时间把程序的执行时间限制死 别的我就没啥办法了