Java 获取本机的外网 IP
原理
通过 HTTP 访问第三方获取 IP 的服务接口获取本机的外网 IP,例如:
- http://checkip.amazonaws.com/
- https://ipv4.icanhazip.com/
- http://bot.whatismyipaddress.com/
- 等等...
下面提供一种方案,并发访问这些服务接口,并返回第一个成功的结果,也就是其中最快的一个返回结果。
实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.regex.Pattern;
public class ExternalIPUtil {/**
* IP 地址校验的正则表达式
*/
private static final Pattern IPV4_PATTERN = Pattern.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
/**
* 获取 IP 地址的服务列表
*/
private static final String[] IPV4_SERVICES = {
"http://checkip.amazonaws.com/",
"https://ipv4.icanhazip.com/",
"http://bot.whatismyipaddress.com/"
// and so on ...
};
public static String get() throws ExecutionException, InterruptedException {
List callables = new ArrayList<>();
for (String ipService : IPV4_SERVICES) {
callables.add(() -> get(ipService));
}ExecutorService executorService = Executors.newCachedThreadPool();
try {
// 返回第一个成功获取的 IP
return executorService.invokeAny(callables);
} finally {
executorService.shutdown();
}
}private static String get(String url) throws IOException {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
String ip = in.readLine();
if (IPV4_PATTERN.matcher(ip).matches()) {
return ip;
} else {
throw new IOException("invalid IPv4 address: " + ip);
}
}
}
}
线程池的
ExecutorService.invokeAny(callables)
方法用于并发执行多个线程,并拿到最快的执行成功的线程的返回值,只要有一个执行成功,其他失败的任务都会忽略。但是如果全部失败,例如本机根本就没有连外网,那么就会抛出 ExecutionException
异常。关注我的公众号
文章图片
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用
- EditText默认不获取焦点弹出键盘