Java检测网络是否连通

159次阅读
没有评论

Java 检测网络是否连通

定时任务来定期执行检测

如果你想在系统运行期间持续检测网络连通性,可以使用定时任务来定期执行检测。

创建了一个 NetworkConnectivityMonitor​类,它启动一个定时任务,每隔指定的时间间隔(以秒为单位)检查目标主机是否可达。当不再需要进行网络连通性检测时,可以通过调用 stopMonitoring()​方法来停止该任务。

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class NetworkConnectivityMonitor {

    private ScheduledExecutorService executorService;

    public void startMonitoring(String host, int checkIntervalInSeconds) {Runnable connectivityCheck = () -> {
            try {if (isReachable(host)) {System.out.println(" 网络连接正常 (" + host + ")");
                } else {System.out.println(" 网络连接不可达 (" + host + ")");
                }
            } catch (UnknownHostException e) {System.err.println(" 无法解析主机名: " + host);
            } catch (IOException e) {System.err.println(" 网络检查过程中发生错误 ");
            }
        };

        executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(connectivityCheck, 0, checkIntervalInSeconds, TimeUnit.SECONDS);
    }

    public void stopMonitoring() {if (executorService != null && !executorService.isShutdown()) {executorService.shutdown();
            System.out.println(" 网络连通性监测已停止 ");
        }
    }

    private boolean isReachable(String host) throws UnknownHostException, IOException {InetAddress address = InetAddress.getByName(host);
        return address.isReachable(5000); // 设置超时时间为 5 秒
    }

    public static void main(String[] args) {NetworkConnectivityMonitor monitor = new NetworkConnectivityMonitor();
        String hostToCheck = "8.8.8.8"; // Google DNS 服务器作为示例
        int checkInterval = 30; // 每隔 30 秒检测一次

        monitor.startMonitoring(hostToCheck, checkInterval);

        // 在某个时候停止监控(例如,在应用程序关闭时)// monitor.stopMonitoring();}
}

注意:实际应用中,你可能还需要处理更多的异常情况,并且根据需求调整检测逻辑和通知机制。

使用 Java 的 NIO 检测

使用 Java 的 NIO(非阻塞 I /O)进行网络连通性检测,可以尝试以下基于 java.nio.channels.SocketChannel​的实现。但是,请注意这种方法可能在处理超时和资源管理方面相对复杂。

使用 SocketChannel​尝试建立到目标主机和端口的连接,并设置了连接超时时间。请注意,这种方法相比前一个基于 InetAddress​或 HttpURLConnection​的解决方案更为复杂,但在某些情况下可能会提供更高的性能和灵活性。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;

public class NetworkConnectivityNIO {public boolean isReachable(String host, int port, int timeoutInMillis) {try (SocketChannel socketChannel = SocketChannel.open()) {socketChannel.socket().setSoTimeout(timeoutInMillis);
            socketChannel.configureBlocking(false);

            InetSocketAddress address = new InetSocketAddress(host, port);

            // 尝试连接
            if (socketChannel.connect(address)) {return true; // 连接成功}

            // 如果在非阻塞模式下 connect() 返回 false,那么需要通过 select() 方法检查连接是否完成
            while (!socketChannel.finishConnect()) {if (Thread.currentThread().isInterrupted()) {return false; // 线程被中断,停止检测}
            }

            return true; // 连接成功
        } catch (IOException e) {return false; // 连接失败}
    }

    public static void main(String[] args) {NetworkConnectivityNIO monitor = new NetworkConnectivityNIO();
        String hostToCheck = "223.5.5.5";
        int portToCheck = 53;//dns 查询端口
        int checkIntervalInSeconds = 10;

        while (true) { // 持续检测
            if (monitor.isReachable(hostToCheck, portToCheck, 5000)) {System.out.println(" 网络连接正常 (" + hostToCheck + ":" + portToCheck + ")");
            } else {System.out.println(" 网络连接不可达 (" + hostToCheck + ":" + portToCheck + ")");
            }

            try {Thread.sleep(checkIntervalInSeconds * 1000);
            } catch (InterruptedException e) {Thread.currentThread().interrupt();
                break;
            }
        }
    }
}
 0
评论(没有评论)
验证码