本文展示一個基於Java的多線程網段掃描程序,能夠在約10秒內掃描500個IP地址,每個IP等待響應時間約0.3秒。程序使用多線程並發ping操作,並通過線程池控制並發數量,避免過多線程導致系統資源耗盡。
package steeven;
import java.sql.*;
import java.io.*;
import java.util.*;
import java.text.*;
import javax.servlet.http.*;
public class Ip extends Common implements Runnable {
public String ip; // IP地址
ResultSet list; // 分頁顯示的記錄集
public Ip cur; // 分頁顯示的當前記錄
static public Hashtable ping = new Hashtable(); // ping後的結果集
static int threadCount = 0; // 當前線程數量,防止過多線程
public Ip() {}
public Ip(String ip) {
this.ip = ip;
Thread r = new Thread(this);
r.start();
}
public static void Ping(String ip) throws Exception {
// 最多30個線程
while (threadCount > 30)
Thread.sleep(50);
threadCount += 1;
Ip p = new Ip(ip);
}
public void PingAll() throws Exception {
threadCount = 0;
ping = new Hashtable();
while (next()) // next()對所有局域網IP放到cur
Ping(cur.ip);
// 等待所有Ping結束
while (threadCount > 0)
Thread.sleep(50);
}
public void run() {
try {
Process p = Runtime.getRuntime().exec("ping " + ip + " -w 300 -n 1");
InputStreamReader ir = new InputStreamReader(p.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
// 讀取結果行
for (int i = 1; i < 7; i++)
input.readLine();
String line = input.readLine();
if (line.length() < 17 || line.substring(8, 17).equals("timed out"))
ping.put(ip, new Boolean(false));
else
ping.put(ip, new Boolean(true));
// 線程結束
threadCount -= 1;
} catch (IOException e) {}
}
public static void main(String[] args) throws Exception {
Ip ip = new Ip();
ip.PingAll();
java.util.Enumeration key = ping.keys();
String k;
while ((k = (String) key.nextElement()) != null)
System.out.println(k + ": " + ping.get(k));
}
}
注意:僅在授權網絡環境中使用,嚴禁未授權掃描他人網絡。