Java Socket域名校验程序抛出UnknownHostException异常求助
解决域名校验程序的
UnknownHostException及代码稳定性问题 你遇到的UnknownHostException本质是程序无法解析bushido.academy这个域名——可能是域名本身不存在、DNS解析失败,或者你的网络环境无法访问这个域名。但更关键的是,你的代码没做好异常兜底,导致遇到单个无效域名就直接崩溃,没法继续处理剩下的条目。咱们一步步来修复这些问题:
1. 补全异常捕获,避免程序崩溃
你的代码只捕获了FileNotFoundException,但网络操作会抛出一堆其他异常(比如UnknownHostException、IOException等),一旦触发就直接终止程序。要把这些异常都捕获,并且在遇到异常时把当前域名标记为错误,写入wrongfile.txt,然后继续循环处理下一个域名。
2. 使用try-with-resources自动管理资源
你现在手动调用br.close()、fw.close()这些,但如果前面的代码抛出异常,这些close语句根本不会执行,会导致文件资源泄漏。Java 7+的try-with-resources可以自动关闭实现了AutoCloseable接口的资源,更安全简洁。
3. 提前校验域名格式
不要直接把读取到的字符串拼HTTP请求,先做格式校验(比如用正则判断是否符合域名规范),避免因为格式错误的域名触发不必要的网络异常。
4. 优化HTTP请求逻辑
- 不要重复调用
setRequestMethod,你先设了GET又设HEAD,最终生效的是HEAD,直接用HEAD就好,它只返回响应头,更轻量。 - 设置请求超时时间,避免因为某个域名长时间无响应卡住程序。
修改后的完整代码
import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; import java.util.regex.Pattern; public class UrlChecker { // 简单的域名格式校验正则(覆盖大部分合法域名场景) private static final Pattern DOMAIN_PATTERN = Pattern.compile( "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$" ); public static void main(String[] args) { // 使用try-with-resources自动关闭所有流资源 try (BufferedReader br = new BufferedReader(new FileReader("test.txt")); FileWriter fw = new FileWriter("wrongfile.txt"); FileWriter ft = new FileWriter("truefile.txt")) { String strLine; while ((strLine = br.readLine()) != null) { strLine = strLine.trim(); // 去除首尾空格 if (strLine.isEmpty()) { continue; // 跳过空行 } System.out.println("Processing: " + strLine); // 第一步:先校验域名格式 if (!DOMAIN_PATTERN.matcher(strLine).matches()) { fw.write(strLine + ":error:Invalid domain format\n"); System.out.println("Domain format invalid: " + strLine); continue; } HttpURLConnection huc = null; try { URL u = new URL("http://" + strLine); huc = (HttpURLConnection) u.openConnection(); huc.setRequestMethod("HEAD"); // 用HEAD请求更轻量,仅获取响应头 huc.setConnectTimeout(5000); // 连接超时5秒 huc.setReadTimeout(5000); // 读取超时5秒 huc.connect(); int coded = huc.getResponseCode(); System.out.println("Response code: " + coded); int code = coded / 100; if (code == 3 || code == 4 || code == 5) { fw.write(strLine + ":error:" + coded + "\n"); System.out.println("Domain not ok: " + coded); } else { ft.write(strLine + "\n"); System.out.println("Domain is ok"); } } catch (MalformedURLException e) { fw.write(strLine + ":error:Malformed URL\n"); System.out.println("Malformed URL for domain: " + strLine); } catch (UnknownHostException e) { fw.write(strLine + ":error:Unknown host\n"); System.out.println("Unknown host: " + strLine); } catch (IOException e) { fw.write(strLine + ":error:IO Exception - " + e.getMessage() + "\n"); System.out.println("IO error for domain: " + strLine + " - " + e.getMessage()); } finally { if (huc != null) { huc.disconnect(); // 手动关闭HTTP连接,释放资源 } } } System.out.println("Processing completed!"); } catch (FileNotFoundException e) { System.err.println("Error: test.txt not found"); } catch (IOException e) { System.err.println("IO error: " + e.getMessage()); } } }
关键改动说明
- 加入域名格式校验,提前过滤无效格式的域名,减少不必要的网络请求。
- 用try-with-resources包裹所有流资源,自动关闭,彻底避免资源泄漏。
- 对每个域名的网络操作单独捕获异常,遇到问题时记录错误并继续处理下一个域名,不会直接崩溃。
- 设置HTTP连接和读取超时,避免程序因某个域名无响应而长时间卡住。
- 关闭HTTP连接,及时释放网络资源。
内容的提问来源于stack exchange,提问作者Abdullah Imran
相关产品推荐
相关产品推荐

