Hashtable(IP → Boolean 可達性)public class IpScanner implements Runnable {
// 靜態共享資源
static Hashtable pingResults = new Hashtable();
static int activeThreads = 0;
static final int MAX_THREADS = 30;
// 掃描目標 IP
private String targetIp;
}
Ping(String ip)public static void Ping(String ip) throws Exception {
// 等待可用線程槽
while (activeThreads > MAX_THREADS)
Thread.sleep(50);
activeThreads++;
new Thread(new IpScanner(ip)).start();
}
run()public void run() {
try {
// 執行系統 ping 命令:Windows 參數 -w 300ms -n 1
Process p = Runtime.getRuntime().exec("ping " + targetIp + " -w 300 -n 1");
InputStreamReader ir = new InputStreamReader(p.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
// 跳過前 6 行標題輸出
for (int i = 1; i < 7; i++) input.readLine();
// 第 7 行包含回應資訊
String line = input.readLine();
boolean reachable = !(line.length() < 17 || line.substring(8, 17).equals("timed out"));
pingResults.put(targetIp, reachable);
} catch (IOException e) {
pingResults.put(targetIp, false);
} finally {
activeThreads--; // 釋放線程槽
}
}
PingAll()public void PingAll() throws Exception {
activeThreads = 0;
pingResults = new Hashtable();
// 遍歷所有目標 IP(需實作 next()/cur.ip 邏輯)
while (next()) {
Ping(cur.ip);
}
// 等待所有線程完成
while (activeThreads > 0)
Thread.sleep(50);
}
原始碼使用 Windows ping 參數(-w 超時毫秒、-n 封包數)。Linux/macOS 需改為 -W 1 -c 1。建議封裝平台差異:
String pingCmd = System.getProperty("os.name").startsWith("Windows")
? "ping -w 300 -n 1 "
: "ping -W 1 -c 1 ";
p.destroy() 或確保 p.waitFor()InputStreamReaderactiveThreads++/-- 應用 AtomicInteger 或 synchronizedInetAddress.isReachable()boolean reachable = InetAddress.getByName(ip).isReachable(300);
優點:跨平台、無需解析文字輸出。缺點:需 ICMP 權限(Linux 需 root),某些防火牆封鎖。
針對 TCP 端口掃描(如 80, 443, 3389),使用 Selector 實現萬級並發,效能遠超進程啟動。
ExecutorService pool = Executors.newFixedThreadPool(30);
for (String ip : targets) {
pool.submit(() -> scanIp(ip));
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.MINUTES);
nbtstat -A 獲取 NetBIOS 名稱、MAC、登入用戶import java.io.*;
import java.util.*;
import java.util.concurrent.*;
public class NetworkScanner {
static ConcurrentMap results = new ConcurrentHashMap<>();
static final int MAX_THREADS = 50;
public static void main(String[] args) throws Exception {
String baseIp = "192.168.1.";
ExecutorService pool = Executors.newFixedThreadPool(MAX_THREADS);
for (int i = 1; i <= 254; i++) {
final String ip = baseIp + i;
pool.submit(() -> {
try {
boolean up = InetAddress.getByName(ip).isReachable(200);
results.put(ip, up);
if (up) System.out.println(ip + " 可達");
} catch (IOException e) {
results.put(ip, false);
}
});
}
pool.shutdown();
pool.awaitTermination(2, TimeUnit.MINUTES);
System.out.println("掃描完成,共 " + results.size() + " 個 IP");
}
}
多線程 Ping 掃描是網路管理基礎工具。原始碼展示了手動線程控制的基本邏輯,但生產環境建議採用線程池、原生 API、跨平台命令適配與資源安全管理。進階需求可延伸為完整資產發現系統。