gpt4 book ai didi

java.net.UnknownHostException 在将日期更改为 future 之后发生

转载 作者:行者123 更新时间:2023-11-29 05:17:27 24 4
gpt4 key购买 nike

按照以下说明操作后出现 java.net.UnknownHostException:

说明:

  1. 断开计算机与互联网的连接(例如:关闭调制解调器)
  2. 将操作系统日期更改为 future 14 天
  3. 运行下面的代码
  4. 点击“执行测试”按钮
  5. 您会收到一条异常消息,但这是正确的,因为互联网已断开连接
  6. 在消息窗口中单击“确定”
  7. 重新连接互联网
  8. 将操作系统日期改回今天的日期
  9. 点击“执行测试”按钮
  10. 您会收到一条异常消息,但您不应该收到,因为已连接互联网
  11. 您可以一次又一次地点击“执行测试”按钮,尽管已连接到互联网,但总是会出现相同的异常。
  12. 如果您在浏览器中测试 URL ( http://test.com) 它将起作用

为什么会这样?我想这不应该发生。

简单代码:

公共(public)类 TestUrlConnection{

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
createAndShowGui();
}
});
}

private static void createAndShowGui(){
final JFrame frame = new JFrame("Test URL Connection");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton btOk = new JButton("Perform Test");
btOk.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
try{
String content = readContentFromTestUrl();
if(content!=null)
JOptionPane.showMessageDialog(frame, "OK. URL Connection returned Content.\nContent length = "+content.length());
else
JOptionPane.showMessageDialog(frame, "Content is null, but no exception");
}
catch(IOException exc){
JOptionPane.showMessageDialog(frame, "Exception:\n\n"+stackTraceToString(exc));
}
}
});

frame.setContentPane(btOk);
frame.setMinimumSize(new Dimension(250,100));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

private static String readContentFromTestUrl() throws IOException{
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;

try {
URL url = new URL("http://test.com");
URLConnection urlConnection = url.openConnection();
urlConnection.setUseCaches(false);

is = urlConnection.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);

String inputLine;
String content = "";

while ((inputLine = br.readLine()) != null)
content += inputLine + "\n";

return content;
}
finally{
if(is!=null){try{is.close();}catch(IOException e){e.printStackTrace();}}
if(isr!=null){try{isr.close();}catch(IOException e){e.printStackTrace();}}
if(br!=null){try{br.close();}catch(IOException e){e.printStackTrace();}}
}
}

private static String stackTraceToString(IOException exc){
exc.printStackTrace();
StringWriter sw = new StringWriter();
exc.printStackTrace(new PrintWriter(sw));
String s = sw.toString();
return s.substring(0, s.length()>600 ? 600 : s.length());
}

最佳答案

DNS 查询非常昂贵,而且它们的结果很少更改,因此几乎每个网络实现都会缓存 DNS 查找结果,这样如果您在几秒钟内打开 100 个连接,它就不必执行 100 个返回相同 IP 地址的 DNS 查询。

Java 实现没有什么不同,它缓存正面和负面(失败的)查询。

默认情况下,负面结果会缓存 10 秒,但显然您的测试指出:

  1. 在执行另一个查找时会检查先前缓存的结果是否有效,从实现的角度来看这很好。
  2. 缓存的构建并没有考虑时钟变化,因此每个实时更改运行 java 网络的服务器的日期的人都应该考虑这一点,以及许多其他不考虑时钟变化的软件包。

所以,发生的事情是 Java 缓存 test.com 是不可解析的。它应该只存在 10 秒,所以它被放置在那里并带有时间戳。如果您更改时钟,这个时间戳不是在 10 秒后失效,而是可能在 14 天 10 秒后失效。

你可以看到它使用了一个缓存值,因为第一次点击按钮会花费很多时间,而其他点击几乎是同步的。

一个简单的解决方案,也证明了问题出在 DNS 缓存中,将此行添加为您的主文件的第一行:

java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "0");

这告诉 java 不要缓存负面的 DNS 结果,如果您尝试,您会发现它会按预期运行。但是,禁用此类缓存会大大降低您的性能,并导致安全问题,因此如果您突然更改计算机的日期,我宁愿建议您重新启动 JVM(以及大多数其他长时间运行的进程)。

关于java.net.UnknownHostException 在将日期更改为 future 之后发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26028871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com