diff --git a/src/main/java/com/tongran/agent/client/core/vo/NetworkInterfaceInfo.java b/src/main/java/com/tongran/agent/client/core/vo/NetworkInterfaceInfo.java index 190e23a..abf4f7e 100644 --- a/src/main/java/com/tongran/agent/client/core/vo/NetworkInterfaceInfo.java +++ b/src/main/java/com/tongran/agent/client/core/vo/NetworkInterfaceInfo.java @@ -6,6 +6,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import java.util.List; + @Data @SuperBuilder @NoArgsConstructor @@ -22,5 +24,10 @@ public class NetworkInterfaceInfo { String province; // 省 String city; // 市 String ipv6; // 市 + // 如果是子接口,存储父接口名称 + private String parentInterface; + + // 如果是父接口,存储子接口列表 + private List subInterfaces; } diff --git a/src/main/java/com/tongran/agent/client/utils/AgentUtil.java b/src/main/java/com/tongran/agent/client/utils/AgentUtil.java index 21407dd..5c3aac7 100644 --- a/src/main/java/com/tongran/agent/client/utils/AgentUtil.java +++ b/src/main/java/com/tongran/agent/client/utils/AgentUtil.java @@ -271,7 +271,7 @@ public class AgentUtil { String name = ni.getName(); // 1. 跳过回环、虚拟、关闭的接口 - if (ni.isLoopback() || ni.isVirtual() || !ni.isUp()) { + if (ni.isLoopback() || !ni.isUp()) { continue; } @@ -308,11 +308,32 @@ public class AgentUtil { return false; } } + /** + * 判断网卡名称是否为子网卡 + * 子网卡通常以冒号加数字结尾(如:eth0:1, enp3s0:2) + * 或点加数字结尾(如:eth1.203, eth1.204, eth1.205) + * + * @param interfaceName 网卡名称 + * @return true-是子网卡,false-不是子网卡 + */ + public static boolean isSubInterface(String interfaceName) { + // 非空检查 + if (interfaceName == null || interfaceName.isEmpty()) { + return false; + } + + // 匹配模式:冒号后跟数字 或 点后跟数字 + String pattern = ".*[:.]\\d+$"; + return interfaceName.matches(pattern); + } /** * 收集所有 Ethernet 类型网卡信息 */ public static List collectNetworkInfo() throws Exception { List result = new ArrayList<>(); + // 使用Map存储父接口,便于快速查找 + Map parentMap = new HashMap<>(); + List childTempList = new ArrayList<>(); Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { @@ -322,7 +343,7 @@ public class AgentUtil { AssertLog.info("ipv4={},接口状态={}",ipv4,ni.isUp()); // 跳过回环、虚拟、关闭的接口 - if (ni.isLoopback() || ni.isVirtual() || !ni.isUp()) continue; + if (ni.isLoopback() || !ni.isUp()) continue; // 判断是否为 Ethernet(通过名称约定:eth*, en*, 等) String name = ni.getName(); @@ -413,7 +434,55 @@ public class AgentUtil { // info.setCity("查询失败"); // } } - result.add(info); + if (isSubInterface(name)) { + AssertLog.info("进入子网卡:{}", name); + // 提取父接口名称 + String parentName = name.replaceAll("[:.]\\d+$", ""); + + // 查找父接口 + NetworkInterfaceInfo parent = parentMap.get(parentName); + if (parent != null) { + // 设置父子关系 + AssertLog.info("设置父子关系:{}", name); + info.setParentInterface(parentName); + if (parent.getSubInterfaces() == null) { + parent.setSubInterfaces(new ArrayList<>()); + } + parent.getSubInterfaces().add(info); + // 子接口不加入result + } else { + AssertLog.info("父网卡还未处理,放入临时列表:{}", name); + // 父接口还未处理,先放到临时列表 + childTempList.add(info); + } + } else { + AssertLog.info("进入父网卡:{}", name); + // 父接口加入Map + parentMap.put(name, info); + } + } + // 处理子接口(父接口未出现的情况) + for (NetworkInterfaceInfo parent : parentMap.values()) { + result.add(parent); + } + // 再处理子接口 + for (NetworkInterfaceInfo child : childTempList) { + String parentName = child.getName().replaceAll("[:.]\\d+$", ""); + NetworkInterfaceInfo parent = parentMap.get(parentName); + + if (parent != null) { + // 建立父子关系 + child.setParentInterface(parentName); + if (parent.getSubInterfaces() == null) { + parent.setSubInterfaces(new ArrayList<>()); + } + AssertLog.info("子网卡:{}", child.getName()); + parent.getSubInterfaces().add(child); + } else { + // 确实没有父接口,作为独立接口 + AssertLog.info("父网卡:{}", child.getName()); + result.add(child); + } } return result;