java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java设置静态IP地址和网关

java实现设置静态IP地址和网关

作者:Katie。

在现代企业网络和嵌入式系统中,静态 IP 配置的需求非常普遍,本项目旨在使用纯 Java的方式,实现对指定网卡的静态 IP,子网掩码,网关,DNS等网络参数的配置,需要的可以了解下

1. 项目背景详细介绍

1.1 引言

在现代企业网络和嵌入式系统中,静态 IP 配置的需求非常普遍。与 DHCP 动态分配相比,静态 IP 最大的优势在于可预测性——管理员可以明确知道设备的网络地址,有利于远程运维、服务发现、安全策略配置等。

然而,Java 应用通常运行于跨平台的 JVM 环境,直接通过 Java 配置网卡并不容易:

操作系统差异:Windows、Linux 在底层网络配置 API、命令行工具上差异巨大。

外部依赖:很多方案依赖外部脚本(如 PowerShell、ifconfig/ip)或 JNI,增加部署复杂度。

可维护性:部署脚本分散,难以统一管理,且不利于二次开发。

本项目旨在使用纯 Java(通过 JNA 调用本地 API 或执行系统命令封装)的方式,实现对指定网卡的静态 IP、子网掩码、网关、DNS 等网络参数的配置,并提供统一接口,以满足跨平台需求。

1.2 需求分析

自动发现网卡:获取本机所有网络接口,并让用户或管理员选择要配置的网卡。

参数配置:设置以下参数:

生效方式:支持 Windows(调用 Netsh 或 WMI)、Linux(调用 ip 或 ifconfig、route),并在执行后刷新或重启网卡。

日志记录:记录每次操作,包括输入参数、执行命令、返回结果、执行时间等,便于排错。

易用接口:封装为工具类或小型库,可在其他 Java 项目中直接调用。

1.3 技术选型

JDK 版本:OpenJDK 11+

核心依赖:

操作系统:

执行方式:Java CLI 工具,或嵌入到更大运维系统中

1.4 系统架构

+------------------------------------------------------+
|                      Java 应用层                     |
|  ┌───────────────┐    ┌───────────────┐    ┌─────────┐ |
|  │ NetworkConfig │ →  │  PlatformExec │ →  │ Logger  │ |
|  └───────────────┘    └───────────────┘    └─────────┘ |
+------------------------------------------------------+
         ↓                            ↓
  JNA/ProcessBuilder               本地系统调用
         ↓                            ↓
    Windows API / Netsh           Linux ip/ifconfig

NetworkConfig:用户接口,接收网卡标识和网络参数。

PlatformExec:根据操作系统类型,调用本地命令或 API。

Logger:统一日志记录。

2. 完整实现代码

说明:以下所有代码都集中在同一个代码块中。不同文件用注释 // 文件:... 区分,且每处核心逻辑均有详细注释。

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.netconfig</groupId>
  <artifactId>netconfig</artifactId>
  <version>1.0.0</version>
  <dependencies>
    <!-- JNA 用于本地调用 -->
    <dependency>
      <groupId>net.java.dev.jna</groupId>
      <artifactId>jna</artifactId>
      <version>5.13.0</version>
    </dependency>
    <!-- SLF4J + Logback -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.36</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
    </dependency>
  </dependencies>
</project>

java

// 文件:src/main/java/com/example/netconfig/NetConfigApp.java
package com.example.netconfig;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.Scanner;
 
/**
 * 主程序入口,提供命令行交互
 */
public class NetConfigApp {
    private static final Logger logger = LoggerFactory.getLogger(NetConfigApp.class);
 
    public static void main(String[] args) {
        logger.info("网络配置工具启动");
        Scanner scanner = new Scanner(System.in);
 
        // 列出所有网卡
        String[] nicList = NetworkUtils.listAllNetworkInterfaces();
        System.out.println("检测到的网络接口:");
        for (int i = 0; i < nicList.length; i++) {
            System.out.printf("%d: %s%n", i, nicList[i]);
        }
 
        // 选择网卡
        System.out.print("请选择要配置的网卡编号:");
        int choice = scanner.nextInt();
        String nicName = nicList[choice];
 
        // 输入网络参数
        System.out.print("请输入静态 IP 地址(如 192.168.1.100):");
        String ip = scanner.next();
        System.out.print("请输入子网掩码(如 255.255.255.0):");
        String mask = scanner.next();
        System.out.print("请输入默认网关(如 192.168.1.1):");
        String gateway = scanner.next();
        System.out.print("请输入首选 DNS(可选,回车跳过):");
        String dns1 = scanner.next();
        System.out.print("请输入备选 DNS(可选,回车跳过):");
        String dns2 = scanner.next();
 
        // 执行配置
        try {
            NetworkConfig config = new NetworkConfig(nicName, ip, mask, gateway, dns1, dns2);
            config.apply();
            logger.info("网络配置完成");
            System.out.println("配置成功!");
        } catch (Exception e) {
            logger.error("配置失败", e);
            System.err.println("配置失败:" + e.getMessage());
        }
    }
}
 
// 文件:src/main/java/com/example/netconfig/NetworkUtils.java
package com.example.netconfig;
 
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
 
/**
 * 网络工具类:列出网卡信息
 */
public class NetworkUtils {
    /**
     * 获取本机所有非回环网卡名称
     * @return 网卡名称数组
     */
    public static String[] listAllNetworkInterfaces() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            List<String> names = new ArrayList<>();
            for (NetworkInterface ni : Collections.list(interfaces)) {
                if (!ni.isLoopback() && ni.isUp()) {
                    names.add(ni.getName());
                }
            }
            return names.toArray(new String[0]);
        } catch (Exception e) {
            throw new RuntimeException("获取网卡列表失败", e);
        }
    }
}
 
// 文件:src/main/java/com/example/netconfig/PlatformExec.java
package com.example.netconfig;
 
import com.sun.jna.Platform;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
/**
 * 平台执行器:在不同操作系统下调用本地命令或 API
 */
public class PlatformExec {
    /**
     * 执行命令行,并返回输出
     * @param cmd 命令数组
     * @throws Exception 执行失败时抛出
     */
    public static void exec(String[] cmd) throws Exception {
        ProcessBuilder pb = new ProcessBuilder(cmd);
        pb.redirectErrorStream(true);
        Process p = pb.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream(), "GBK"));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        int code = p.waitFor();
        if (code != 0) {
            throw new RuntimeException("命令执行失败,退出码:" + code);
        }
    }
 
    /**
     * 判断当前操作系统是否为 Windows
     */
    public static boolean isWindows() {
        return Platform.isWindows();
    }
}
 
// 文件:src/main/java/com/example/netconfig/NetworkConfig.java
package com.example.netconfig;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
 * 网络配置主类:封装网络参数并执行配置
 */
public class NetworkConfig {
    private static final Logger logger = LoggerFactory.getLogger(NetworkConfig.class);
 
    private final String nicName;
    private final String ip;
    private final String mask;
    private final String gateway;
    private final String dns1;
    private final String dns2;
 
    public NetworkConfig(String nicName, String ip, String mask, String gateway, String dns1, String dns2) {
        this.nicName = nicName;
        this.ip = ip;
        this.mask = mask;
        this.gateway = gateway;
        this.dns1 = dns1;
        this.dns2 = dns2;
    }
 
    /**
     * 应用网络配置:根据操作系统调用不同实现
     */
    public void apply() throws Exception {
        logger.info("开始配置网卡:{}", nicName);
        if (PlatformExec.isWindows()) {
            applyWindows();
        } else {
            applyLinux();
        }
    }
 
    /**
     * Windows 下调用 netsh 命令配置
     */
    private void applyWindows() throws Exception {
        // 设置静态 IP 和子网掩码
        String[] cmdIp = {
            "netsh", "interface", "ip", "set", "address",
            "name=" + nicName, "static", ip, mask, gateway, "1"
        };
        logger.debug("执行命令:{}", String.join(" ", cmdIp));
        PlatformExec.exec(cmdIp);
 
        // 配置 DNS(如果提供)
        if (dns1 != null && !dns1.isEmpty()) {
            String[] cmdDns1 = {
                "netsh", "interface", "ip", "set", "dns",
                "name=" + nicName, "static", dns1, "primary"
            };
            logger.debug("执行命令:{}", String.join(" ", cmdDns1));
            PlatformExec.exec(cmdDns1);
        }
        if (dns2 != null && !dns2.isEmpty()) {
            String[] cmdDns2 = {
                "netsh", "interface", "ip", "add", "dns",
                "name=" + nicName, dns2, "index=2"
            };
            logger.debug("执行命令:{}", String.join(" ", cmdDns2));
            PlatformExec.exec(cmdDns2);
        }
    }
 
    /**
     * Linux 下调用 ip、route 命令配置
     */
    private void applyLinux() throws Exception {
        // 删除原有 IP
        PlatformExec.exec(new String[]{"sudo", "ip", "addr", "flush", "dev", nicName});
        // 添加新 IP
        PlatformExec.exec(new String[]{"sudo", "ip", "addr", "add", ip + "/" + maskToPrefix(mask), "dev", nicName});
        // 设置网关
        PlatformExec.exec(new String[]{"sudo", "ip", "route", "add", "default", "via", gateway, "dev", nicName});
        // DNS 写入 /etc/resolv.conf
        if (dns1 != null && !dns1.isEmpty()) {
            String resolv = "nameserver " + dns1 + "\n" + (dns2 != null && !dns2.isEmpty() ? "nameserver " + dns2 + "\n" : "");
            // 写文件(需 root 权限),这里简化为 echo
            PlatformExec.exec(new String[]{"sudo", "bash", "-c", "echo -e \"" + resolv + "\" > /etc/resolv.conf"});
        }
    }
 
    /**
     * 将子网掩码转换为前缀长度,如 255.255.255.0 → 24
     */
    private String maskToPrefix(String mask) {
        String[] octets = mask.split("\\.");
        int bits = 0;
        for (String o : octets) {
            int v = Integer.parseInt(o);
            bits += Integer.bitCount(v);
        }
        return String.valueOf(bits);
    }
}

3. 项目详细总结

1.功能实现

使用 Java + JNA/ProcessBuilder 实现跨平台的静态 IP、子网掩码、网关及 DNS 配置。

Windows 平台通过 netsh 命令,Linux 平台通过 ip、route 及 resolv.conf 进行配置。

日志记录全流程,便于审计与故障排查。

2.代码亮点

纯 Java 封装:无需额外脚本,只需 JVM 即可运行。

动态 网卡发现:利用 NetworkInterface 自动列出可用网卡。

可扩展性:若将来支持 macOS,只需在 PlatformExec 中添加对应实现。

教学价值:JNA 调用与命令执行示例结合,适合学习与示范。

3.使用注意

Windows 上需以管理员身份运行;Linux 上需具备 sudo 权限或 root 执行。

对于服务器场景,建议将该工具作为系统服务或与运维平台集成。

修改 DNS 时直接覆盖 /etc/resolv.conf,在某些发行版(如使用 NetworkManager)下需注意冲突。

4.后续改进

增加 macOS 支持,调用 networksetup 工具。

提供图形化界面或 Web 管理界面。

集成配置回退机制,当新配置异常时自动恢复原有设置。

支持更多网络参数(如 MTU、VLAN、多个网关策略等)。

到此这篇关于java实现设置静态IP地址和网关的文章就介绍到这了,更多相关java设置静态IP地址和网关内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文