package com.tongran.agent.client.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class PublicIpFetcher { private static final String IP_SERVICE_URL = "https://myip.ipip.net"; private static final int TIMEOUT_MS = 10_000; // 10秒超时 /** * 获取公网 IP(包含归属地信息) * * @return IP 信息字符串,如 "当前 IP:112.96.15.145,来自于:中国 广东省 深圳市 联通" * @throws IOException 如果网络请求失败 */ public static String getPublicIp() throws IOException { URL url = new URL(IP_SERVICE_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法 connection.setRequestMethod("GET"); connection.setConnectTimeout(TIMEOUT_MS); connection.setReadTimeout(TIMEOUT_MS); // 发起请求 int responseCode = connection.getResponseCode(); if (responseCode != 200) { throw new IOException("HTTP " + responseCode + " from " + IP_SERVICE_URL); } // 读取响应(注意:myip.ipip.net 返回的是 GBK 编码) try (BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream(), "GBK"))) { // 使用 GBK 解码 StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } return response.toString().trim(); } } /** * 从返回文本中提取纯 IP 地址(如 112.96.15.145) * * @param ipInfo 来自 getPublicIp() 的完整信息 * @return 纯 IP 字符串,提取失败返回 null */ public static String extractIp(String ipInfo) { if (ipInfo == null || ipInfo.isEmpty()) return null; // 匹配 IP 地址的正则 java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"); java.util.regex.Matcher matcher = pattern.matcher(ipInfo); return matcher.find() ? matcher.group(1) : null; } // === 使用示例 === public static void main(String[] args) { try { String ipInfo = getPublicIp(); System.out.println("完整信息: " + ipInfo); String pureIp = extractIp(ipInfo); if (pureIp != null) { System.out.println("公网 IP: " + pureIp); } else { System.out.println("未能提取 IP 地址"); } } catch (IOException e) { System.err.println("获取公网 IP 失败: " + e.getMessage()); e.printStackTrace(); } } }