Java实现获取当前局域网下所有连接设备的IP地址和MAC地址
下面展示一些 内联代码片
。
首先先将全部代码交出给各位在慢慢详细讲解
package com.example.sdj_administrationapplication.abnormal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NetworkScanner {
public static void main(String[] args) throws IOException, InterruptedException {
// 是否进行初始扫描
boolean initSearch = false;
if (initSearch) {
System.out.println("正在扫描当前网段所有ip,预计耗时1分钟....");
String netSegment = getNetSegment();
if (netSegment != null) {
pingNetSegmentAll(netSegment);
} else {
System.out.println("Failed to get network segment.");
return;
}
}
List<Device> last = null;
while (true) {
List<Device> currentDevices = getArpIpMac();
if (last == null) {
System.out.println("当前在线的设备:");
printDevices(currentDevices);
} else {
List<Device> online = getOnlineDevices(last, currentDevices);
if (!online.isEmpty()) {
System.out.println("新上线设备:");
printDevices(online);
}
List<Device> offline = getOfflineDevices(last, currentDevices);
if (!offline.isEmpty()) {
System.out.println("刚下线设备:");
printDevices(offline);
}
}
TimeUnit.SECONDS.sleep(5);
pingIpList(getIpAddresses(currentDevices));
last = currentDevices;
}
}
private static String getNetSegment() throws IOException {
Process process = Runtime.getRuntime().exec("arp -a");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
Pattern pattern = Pattern.compile("(\\d+\\.\\d+\\.\\d+)\\.\\d+");
while ((line = reader.readLine()) != null) {
if (line.startsWith("接口") || line.startsWith("Interface")) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
return matcher.group(1);
}
}
}
}
return null;
}
private static void pingNetSegmentAll(String netSegment) {
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 1; i < 255; i++) {
String ip = netSegment + "." + i;
executor.submit(() -> {
try {
Runtime.getRuntime().exec("ping -w 1 -n 1 " + ip);
} catch (IOException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static List<Device> getArpIpMac() throws IOException {
List<Device> devices = new ArrayList<>();
Process process = Runtime.getRuntime().exec("arp -a");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
boolean headerParsed = false;
while ((line = reader.readLine()) != null) {
if (line.startsWith("接口") || line.startsWith("Interface")) {
continue;
}
if (!headerParsed) {
headerParsed = true;
continue;
}
String[] fields = line.trim().split("\\s+");
if (fields.length >= 3 && "动态".equals(fields[2])) {
devices.add(new Device(fields[0], fields[1]));
}
}
}
return devices;
}
private static void pingIpList(List<String> ips) throws InterruptedException {
System.out.println("正在扫描在线列表");
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<?>> futures = new ArrayList<>();
for (String ip : ips) {
futures.add(executor.submit(() -> {
try {
Runtime.getRuntime().exec("ping -w 1 -n 1 " + ip);
} catch (IOException e) {
e.printStackTrace();
}
}));
}
for (Future<?> future : futures) {
try {
future.get();
} catch (Exception e) {
e.printStackTrace();
}
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
}
private static List<Device> getOnlineDevices(List<Device> last, List<Device> current) {
List<Device> online = new ArrayList<>(current);
online.removeAll(last);
return online;
}
private static List<Device> getOfflineDevices(List<Device> last, List<Device> current) {
List<Device> offline = new ArrayList<>(last);
offline.removeAll(current);
return offline;
}
private static List<String> getIpAddresses(List<Device> devices) {
List<String> ips = new ArrayList<>();
for (Device device : devices) {
ips.add(device.getIpAddress());
}
return ips;
}
private static void printDevices(List<Device> devices) {
for (Device device : devices) {
System.out.println(device);
}
}
}
class Device {
private String ipAddress;
private String macAddress;
public Device(String ipAddress, String macAddress) {
this.ipAddress = ipAddress;
this.macAddress = macAddress;
}
public String getIpAddress() {
return ipAddress;
}
public String getMacAddress() {
return macAddress;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Device device = (Device) o;
return ipAddress.equals(device.ipAddress) && macAddress.equals(device.macAddress);
}
@Override
public int hashCode() {
return Objects.hash(ipAddress, macAddress);
}
@Override
public String toString() {
return "IP Address: " + ipAddress + ", MAC Address: " + macAddress;
}
}
第一
public static void main(String[] args) throws IOException, InterruptedException {
// 是否进行初始扫描 程序的入口点,表示程序从这里开始执行
boolean initSearch = false;
//一个布尔变量,用于标记是否执行初始扫描。如果设置为 true,则程序会执行初始扫描;如果
//设置为 false,则直接进入主循环。
if (initSearch) {
//果执行初始扫描的标志为 true,则执行以下代码块。
System.out.println("正在扫描当前网段所有ip,预计耗时1分钟....");
//打印提示消息,表示程序正在执行初始扫描。
String netSegment = getNetSegment();
//调用 getNetSegment() 方法,获取当前局域网的网段信息
if (netSegment != null) {
pingNetSegmentAll(netSegment);
} else {
//如果获取网段信息失败,则打印错误消息并退出程序。
System.out.println("Failed to get network segment.");
return;
}
}
//声明一个 Device 类型的列表变量 last,用于保存上一次扫描到的设备列表。初始值为 null。
List<Device> last = null;
while (true) {
//进入主循环,程序会持续执行直到手动终止。
List<Device> currentDevices = getArpIpMac();
//调用 getArpIpMac() 方法,获取当前局域网中在线的设备列表。
if (last == null) {
//如果上一次扫描到的设备列表为空(即第一次扫描),则执行以下代码块。
System.out.println("当前在线的设备:");
//打印提示消息,表示当前在线的设备列表即将输出
printDevices(currentDevices);
} else {
//如果不是第一次扫描,则执行以下代码块。结束新上线设备的判断。
List<Device> online = getOnlineDevices(last, currentDevices);
//调用 getOnlineDevices() 方法,获取新上线的设备列表。
if (!online.isEmpty()) {
//如果新上线的设备列表不为空,则执行以下代码块。
System.out.println("新上线设备:");
printDevices(online);
}
//调用 getOfflineDevices() 方法,获取刚下线的设备列表。
List<Device> offline = getOfflineDevices(last, currentDevices);
if (!offline.isEmpty()) {
//如果刚下线的设备列表不为空,则执行以下代码块
System.out.println("刚下线设备:");
printDevices(offline);
}
}
//结束主循环的大括号
TimeUnit.SECONDS.sleep(5);
pingIpList(getIpAddresses(currentDevices));
last = currentDevices;
}
}
第二 太多了剩下的就简单的说一下不懂得发评论里面
getNetSegment(): 这个方法用于获取当前计算机所在局域网的网段。它执行命令 arp -a 来获取本地 ARP 缓存表的信息,并解析其中的接口信息来确定网段。
pingNetSegmentAll(String netSegment): 这个方法用于对当前网段中的所有 IP 地址进行 ping 操作,以便发现在线的设备。它通过循环从 1 到 254 遍历网段中的所有可能 IP 地址,并使用线程池并行地执行 ping 操作。
getArpIpMac(): 这个方法用于获取局域网中在线设备的 IP 地址和 MAC 地址。它同样执行命令 arp -a 来获取本地 ARP 缓存表的信息,并解析其中的动态条目,提取出 IP 地址和 MAC 地址。然后将这些信息封装成 Device 对象,并以列表的形式返回。
private static String getNetSegment() throws IOException {
Process process = Runtime.getRuntime().exec("arp -a");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
Pattern pattern = Pattern.compile("(\\d+\\.\\d+\\.\\d+)\\.\\d+");
while ((line = reader.readLine()) != null) {
if (line.startsWith("接口") || line.startsWith("Interface")) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
return matcher.group(1);
}
}
}
}
return null;
}
private static void pingNetSegmentAll(String netSegment) {
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 1; i < 255; i++) {
String ip = netSegment + "." + i;
executor.submit(() -> {
try {
Runtime.getRuntime().exec("ping -w 1 -n 1 " + ip);
} catch (IOException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static List<Device> getArpIpMac() throws IOException {
List<Device> devices = new ArrayList<>();
Process process = Runtime.getRuntime().exec("arp -a");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
boolean headerParsed = false;
while ((line = reader.readLine()) != null) {
if (line.startsWith("接口") || line.startsWith("Interface")) {
continue;
}
if (!headerParsed) {
headerParsed = true;
continue;
}
String[] fields = line.trim().split("\\s+");
if (fields.length >= 3 && "动态".equals(fields[2])) {
devices.add(new Device(fields[0], fields[1]));
}
}
}
return devices;
}
第三 最后
pingIpList(List ips): 这个方法用于对给定的 IP 地址列表进行 ping 操作,以便判断设备是否在线。它通过创建线程池,并且为每个 IP 地址提交一个 ping 操作的任务,来并行地执行 ping 操作。这个方法的目的是为了检测设备的在线状态。
getOnlineDevices(List last, List current): 这个方法用于获取当前在线的设备列表。它接收两个参数:上一次扫描到的设备列表 last 和当前扫描到的设备列表 current。它通过比较这两个列表,找出在 current 列表中存在但在 last 列表中不存在的设备,从而得到当前新增上线的设备列表。
getOfflineDevices(List last, List current): 这个方法用于获取当前下线的设备列表。它接收两个参数:上一次扫描到的设备列表 last 和当前扫描到的设备列表 current。它通过比较这两个列表,找出在 last 列表中存在但在 current 列表中不存在的设备,从而得到当前新下线的设备列表。
getIpAddresses(List devices): 这个方法用于从设备列表中提取出所有设备的 IP 地址。它接收一个设备列表作为参数,并遍历这个列表,将每个设备的 IP 地址添加到一个新的列表中,最后返回这个包含所有设备 IP 地址的列表。
printDevices(List devices): 这个方法用于打印设备信息。它接收一个设备列表作为参数,并遍历这个列表,打印每个设备的 IP 地址和 MAC 地址。
Device 类是一个简单的封装了设备的 IP 地址和 MAC 地址的实体类,提供了适当的构造函数和重写的 equals()、hashCode()、toString() 方法。
private static void pingIpList(List<String> ips) throws InterruptedException {
System.out.println("正在扫描在线列表");
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<?>> futures = new ArrayList<>();
for (String ip : ips) {
futures.add(executor.submit(() -> {
try {
Runtime.getRuntime().exec("ping -w 1 -n 1 " + ip);
} catch (IOException e) {
e.printStackTrace();
}
}));
}
for (Future<?> future : futures) {
try {
future.get();
} catch (Exception e) {
e.printStackTrace();
}
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
}
private static List<Device> getOnlineDevices(List<Device> last, List<Device> current) {
List<Device> online = new ArrayList<>(current);
online.removeAll(last);
return online;
}
private static List<Device> getOfflineDevices(List<Device> last, List<Device> current) {
List<Device> offline = new ArrayList<>(last);
offline.removeAll(current);
return offline;
}
private static List<String> getIpAddresses(List<Device> devices) {
List<String> ips = new ArrayList<>();
for (Device device : devices) {
ips.add(device.getIpAddress());
}
return ips;
}
private static void printDevices(List<Device> devices) {
for (Device device : devices) {
System.out.println(device);
}
}
}
class Device {
private String ipAddress;
private String macAddress;
public Device(String ipAddress, String macAddress) {
this.ipAddress = ipAddress;
this.macAddress = macAddress;
}
public String getIpAddress() {
return ipAddress;
}
public String getMacAddress() {
return macAddress;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Device device = (Device) o;
return ipAddress.equals(device.ipAddress) && macAddress.equals(device.macAddress);
}
@Override
public int hashCode() {
return Objects.hash(ipAddress, macAddress);
}
@Override
public String toString() {
return "IP Address: " + ipAddress + ", MAC Address: " + macAddress;
}
}
大概就是这些,有不懂地方可以发评论或者私信