定时任务来定期执行检测
如果你想在系统运行期间持续检测网络连通性,可以使用定时任务来定期执行检测。
创建了一个 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;
}
}
}
}