本文最后更新于 2025-10-29,文章内容可能已经过时。

在Java中判断网络是否正常连接有几种常用方法,下面我将详细介绍几种实现方式,并说明它们的优缺点。

1. 使用InetAddress的isReachable()方法(推荐)

这是Java标准API提供的方法,不需要执行系统命令,相对更可靠和跨平台。

import java.net.InetAddress;

public class NetworkChecker {
    public static boolean isInternetConnected() {
        try {
            // 尝试连接Google DNS服务器(8.8.8.8),设置2秒超时
            InetAddress address = InetAddress.getByName("8.8.8.8");
            return address.isReachable(2000); // 2秒超时
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) {
        if (isInternetConnected()) {
            System.out.println("网络连接正常");
        } else {
            System.out.println("网络连接异常");
        }
    }
}

优点

  • 使用Java标准API,不需要执行系统命令
  • 跨平台性好
  • 代码简洁

缺点

  • 可能受防火墙影响(某些防火墙会阻止ICMP请求)
  • 依赖于目标服务器的可达性

2. 使用ping命令执行系统命令

这是比较传统的方法,通过执行系统ping命令来判断网络状态。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class NetworkChecker {
    public static boolean isInternetConnected() {
        try {
            // 检测操作系统类型
            String os = System.getProperty("os.name").toLowerCase();
            boolean isWindows = os.contains("win");
            boolean isLinuxOrMac = os.contains("nix") || os.contains("nux") || os.contains("mac");
            
            // 根据操作系统选择正确的ping命令参数
            String pingCommand;
            if (isWindows) {
                // Windows: ping -n <count> <host>
                pingCommand = "ping -n 4 www.baidu.com";
            } else {
                // Linux/MacOS: ping -c <count> <host>
                pingCommand = "ping -c 4 www.baidu.com";
            }
            // 执行ping命令
            Process process = Runtime.getRuntime().exec(pingCommand);
            // 读取输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            boolean isReachable = false;
            // 读取ping命令的输出
            while ((line = reader.readLine()) != null) {
                // 检查输出中是否包含成功信息
                if (isWindows) {
                    // Windows系统:检查是否包含"TTL"
                    if (line.contains("TTL")) {
                        isReachable = true;
                    }
                } else {
                    // Linux/MacOS系统:检查是否包含"time="
                    if (line.contains("time=")) {
                        isReachable = true;
                    }
                }
            }
            // 等待命令执行完成
            int exitCode = process.waitFor();
            return isReachable && exitCode == 0;
        } catch (IOException | InterruptedException e) {
            return false;
        }
    }

    public static void main(String[] args) {
        if (isInternetConnected()) {
            System.out.println("网络连接正常");
        } else {
            System.out.println("网络连接异常");
        }
    }
}

优点

  • 结果比较准确,接近真实的ping命令
  • 可以通过修改命令参数来适应不同操作系统

缺点

  • 依赖于操作系统,不同系统命令格式不同
  • 需要执行系统命令,可能有安全风险
  • 需要处理不同系统的输出格式差异

3. 使用URL连接测试

这种方法通过HTTP请求测试网络连接。

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

public class NetworkChecker {
    public static boolean isInternetConnected() {
        try {
            URL url = new URL("http://www.baidu.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("HEAD");
            connection.setConnectTimeout(2000); // 2秒超时
            connection.connect();
            return connection.getResponseCode() == 200;
        } catch (IOException e) {
            return false;
        }
    }

    public static void main(String[] args) {
        if (isInternetConnected()) {
            System.out.println("网络连接正常");
        } else {
            System.out.println("网络连接异常");
        }
    }
}
import java.net.*;
import java.io.*;
import javax.net.ssl.*;

public class NetworkChecker {
    public static boolean isInternetConnected() {
        try {
            // 创建一个信任所有证书的SSL上下文
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
            }}, new java.security.SecureRandom());
            
            // 设置默认的SSL上下文
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
            
            URL url = new URL("https://blog.nn3n.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("HEAD");
            connection.setConnectTimeout(2000); // 2秒超时
            connection.connect();
            return connection.getResponseCode() == 200;
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) {
        if (isInternetConnected()) {
            System.out.println("网络连接正常");
        } else {
            System.out.println("网络连接异常");
        }
    }
}

优点

  • 可以测试HTTP连接,更贴近实际应用
  • 不受ICMP限制(有些防火墙允许HTTP但阻止ICMP)

缺点

  • 依赖于目标网站的可用性
  • 需要能够访问HTTP服务

4. 使用Socket连接测试

通过尝试连接到常用端口来判断网络连通性。

import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

public class NetworkChecker {
    public static boolean isInternetConnected() {
        try {
            // 尝试连接到Google DNS服务器的53端口(DNS服务)
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress("8.8.8.8", 53), 2000);
            socket.close();
            return true;
        } catch (SocketTimeoutException e) {
            // 连接超时
            return false;
        } catch (Exception e) {
            // 其他异常
            return false;
        }
    }

    public static void main(String[] args) {
        if (isInternetConnected()) {
            System.out.println("网络连接正常");
        } else {
            System.out.println("网络连接异常");
        }
    }
}

优点

  • 可以测试特定端口的连通性
  • 相对快速

缺点

  • 依赖于特定端口的可用性
  • 可能受防火墙影响

选择哪种方法?

  • 推荐使用InetAddress.isReachable():这是Java标准API,简单可靠,大多数情况下都能正常工作。
  • 如果需要更精确的网络检测:可以结合多种方法,例如先尝试isReachable(),如果失败再尝试ping命令。
  • 考虑防火墙影响:某些网络环境可能阻止ICMP请求(ping),这时使用HTTP或Socket连接测试会更可靠。

注意事项

  1. 防火墙问题:很多防火墙会阻止ICMP请求(ping),这可能导致ping命令方法失败,但实际网络是连通的。
  2. 超时设置:设置合理的超时时间(如2000毫秒),避免长时间等待。
  3. 网络类型:如果是移动设备,可能需要考虑Wi-Fi和移动数据网络的区别。
  4. 权限问题:在某些环境中执行系统命令可能需要额外权限。

以上方法中,InetAddress.isReachable()是最简单、最常用的方法,推荐优先使用。如果遇到问题,可以尝试其他方法作为备选。