java實現(xiàn)設置靜態(tài)IP地址和網(wǎng)關
1. 項目背景詳細介紹
1.1 引言
在現(xiàn)代企業(yè)網(wǎng)絡和嵌入式系統(tǒng)中,靜態(tài) IP 配置的需求非常普遍。與 DHCP 動態(tài)分配相比,靜態(tài) IP 最大的優(yōu)勢在于可預測性——管理員可以明確知道設備的網(wǎng)絡地址,有利于遠程運維、服務發(fā)現(xiàn)、安全策略配置等。
然而,Java 應用通常運行于跨平臺的 JVM 環(huán)境,直接通過 Java 配置網(wǎng)卡并不容易:
操作系統(tǒng)差異:Windows、Linux 在底層網(wǎng)絡配置 API、命令行工具上差異巨大。
外部依賴:很多方案依賴外部腳本(如 PowerShell、ifconfig/ip)或 JNI,增加部署復雜度。
可維護性:部署腳本分散,難以統(tǒng)一管理,且不利于二次開發(fā)。
本項目旨在使用純 Java(通過 JNA 調(diào)用本地 API 或執(zhí)行系統(tǒng)命令封裝)的方式,實現(xiàn)對指定網(wǎng)卡的靜態(tài) IP、子網(wǎng)掩碼、網(wǎng)關、DNS 等網(wǎng)絡參數(shù)的配置,并提供統(tǒng)一接口,以滿足跨平臺需求。
1.2 需求分析
自動發(fā)現(xiàn)網(wǎng)卡:獲取本機所有網(wǎng)絡接口,并讓用戶或管理員選擇要配置的網(wǎng)卡。
參數(shù)配置:設置以下參數(shù):
- IP 地址
- 子網(wǎng)掩碼
- 默認網(wǎng)關
- DNS(首選/備選,可選)
生效方式:支持 Windows(調(diào)用 Netsh 或 WMI)、Linux(調(diào)用 ip 或 ifconfig、route),并在執(zhí)行后刷新或重啟網(wǎng)卡。
日志記錄:記錄每次操作,包括輸入?yún)?shù)、執(zhí)行命令、返回結(jié)果、執(zhí)行時間等,便于排錯。
易用接口:封裝為工具類或小型庫,可在其他 Java 項目中直接調(diào)用。
1.3 技術選型
JDK 版本:OpenJDK 11+
核心依賴:
- JNA (Java Native Access):跨平臺調(diào)用本地系統(tǒng) API
- SLF4J + Logback:日志記錄
操作系統(tǒng):
- Windows 7/10/Server 2012+
- Linux 發(fā)行版(Ubuntu/Debian/CentOS 等)
執(zhí)行方式:Java CLI 工具,或嵌入到更大運維系統(tǒng)中
1.4 系統(tǒng)架構(gòu)
+------------------------------------------------------+
| Java 應用層 |
| ┌───────────────┐ ┌───────────────┐ ┌─────────┐ |
| │ NetworkConfig │ → │ PlatformExec │ → │ Logger │ |
| └───────────────┘ └───────────────┘ └─────────┘ |
+------------------------------------------------------+
↓ ↓
JNA/ProcessBuilder 本地系統(tǒng)調(diào)用
↓ ↓
Windows API / Netsh Linux ip/ifconfig
NetworkConfig:用戶接口,接收網(wǎng)卡標識和網(wǎng)絡參數(shù)。
PlatformExec:根據(jù)操作系統(tǒng)類型,調(diào)用本地命令或 API。
Logger:統(tǒng)一日志記錄。
2. 完整實現(xiàn)代碼
說明:以下所有代碼都集中在同一個代碼塊中。不同文件用注釋 // 文件:... 區(qū)分,且每處核心邏輯均有詳細注釋。
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 用于本地調(diào)用 -->
<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("網(wǎng)絡配置工具啟動");
Scanner scanner = new Scanner(System.in);
// 列出所有網(wǎng)卡
String[] nicList = NetworkUtils.listAllNetworkInterfaces();
System.out.println("檢測到的網(wǎng)絡接口:");
for (int i = 0; i < nicList.length; i++) {
System.out.printf("%d: %s%n", i, nicList[i]);
}
// 選擇網(wǎng)卡
System.out.print("請選擇要配置的網(wǎng)卡編號:");
int choice = scanner.nextInt();
String nicName = nicList[choice];
// 輸入網(wǎng)絡參數(shù)
System.out.print("請輸入靜態(tài) IP 地址(如 192.168.1.100):");
String ip = scanner.next();
System.out.print("請輸入子網(wǎng)掩碼(如 255.255.255.0):");
String mask = scanner.next();
System.out.print("請輸入默認網(wǎng)關(如 192.168.1.1):");
String gateway = scanner.next();
System.out.print("請輸入首選 DNS(可選,回車跳過):");
String dns1 = scanner.next();
System.out.print("請輸入備選 DNS(可選,回車跳過):");
String dns2 = scanner.next();
// 執(zhí)行配置
try {
NetworkConfig config = new NetworkConfig(nicName, ip, mask, gateway, dns1, dns2);
config.apply();
logger.info("網(wǎng)絡配置完成");
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;
/**
* 網(wǎng)絡工具類:列出網(wǎng)卡信息
*/
public class NetworkUtils {
/**
* 獲取本機所有非回環(huán)網(wǎng)卡名稱
* @return 網(wǎng)卡名稱數(shù)組
*/
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("獲取網(wǎng)卡列表失敗", 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;
/**
* 平臺執(zhí)行器:在不同操作系統(tǒng)下調(diào)用本地命令或 API
*/
public class PlatformExec {
/**
* 執(zhí)行命令行,并返回輸出
* @param cmd 命令數(shù)組
* @throws Exception 執(zhí)行失敗時拋出
*/
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("命令執(zhí)行失敗,退出碼:" + code);
}
}
/**
* 判斷當前操作系統(tǒng)是否為 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;
/**
* 網(wǎng)絡配置主類:封裝網(wǎng)絡參數(shù)并執(zhí)行配置
*/
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;
}
/**
* 應用網(wǎng)絡配置:根據(jù)操作系統(tǒng)調(diào)用不同實現(xiàn)
*/
public void apply() throws Exception {
logger.info("開始配置網(wǎng)卡:{}", nicName);
if (PlatformExec.isWindows()) {
applyWindows();
} else {
applyLinux();
}
}
/**
* Windows 下調(diào)用 netsh 命令配置
*/
private void applyWindows() throws Exception {
// 設置靜態(tài) IP 和子網(wǎng)掩碼
String[] cmdIp = {
"netsh", "interface", "ip", "set", "address",
"name=" + nicName, "static", ip, mask, gateway, "1"
};
logger.debug("執(zhí)行命令:{}", 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("執(zhí)行命令:{}", 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("執(zhí)行命令:{}", String.join(" ", cmdDns2));
PlatformExec.exec(cmdDns2);
}
}
/**
* Linux 下調(diào)用 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});
// 設置網(wǎng)關
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"});
}
}
/**
* 將子網(wǎng)掩碼轉(zhuǎn)換為前綴長度,如 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. 項目詳細總結(jié)
1.功能實現(xiàn)
使用 Java + JNA/ProcessBuilder 實現(xiàn)跨平臺的靜態(tài) IP、子網(wǎng)掩碼、網(wǎng)關及 DNS 配置。
Windows 平臺通過 netsh 命令,Linux 平臺通過 ip、route 及 resolv.conf 進行配置。
日志記錄全流程,便于審計與故障排查。
2.代碼亮點
純 Java 封裝:無需額外腳本,只需 JVM 即可運行。
動態(tài) 網(wǎng)卡發(fā)現(xiàn):利用 NetworkInterface 自動列出可用網(wǎng)卡。
可擴展性:若將來支持 macOS,只需在 PlatformExec 中添加對應實現(xiàn)。
教學價值:JNA 調(diào)用與命令執(zhí)行示例結(jié)合,適合學習與示范。
3.使用注意
Windows 上需以管理員身份運行;Linux 上需具備 sudo 權限或 root 執(zhí)行。
對于服務器場景,建議將該工具作為系統(tǒng)服務或與運維平臺集成。
修改 DNS 時直接覆蓋 /etc/resolv.conf,在某些發(fā)行版(如使用 NetworkManager)下需注意沖突。
4.后續(xù)改進
增加 macOS 支持,調(diào)用 networksetup 工具。
提供圖形化界面或 Web 管理界面。
集成配置回退機制,當新配置異常時自動恢復原有設置。
支持更多網(wǎng)絡參數(shù)(如 MTU、VLAN、多個網(wǎng)關策略等)。
到此這篇關于java實現(xiàn)設置靜態(tài)IP地址和網(wǎng)關的文章就介紹到這了,更多相關java設置靜態(tài)IP地址和網(wǎng)關內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
通過簡單方法實現(xiàn)spring boot web項目
這篇文章主要介紹了通過簡單方法實現(xiàn)spring boot web項目,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09

