在我的 Java 客户端应用程序中,我使用 HttpsURLConnection 连接到我的服务器。这一切都很好,除了在某些时刻它根本不会超时。我将连接的超时参数设置为(5000 毫秒):
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
// timeouts
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
con.setRequestMethod("put");
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestProperty("Content-length", String.valueOf(output.length()));
OutputStreamWriter os = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
BufferedWriter writer = new BufferedWriter(os);
writer.write(output);
writer.close();
os.close();
con.connect();
int respCode = con.getResponseCode();
if(respCode == 200) {
InputStreamReader is = new InputStreamReader(con.getInputStream());
BufferedReader br = new BufferedReader(is);
String input;
String respBody = "";
while ((input = br.readLine()) != null){
respBody += input;
}
br.close();
is.close();
this.result = respBody;
}
我捕获了所有异常,但没有注册任何异常,因此问题不可能是未捕获的异常。连接根本不会超时。我等了3分钟,没有任何反应。在执行请求期间切换网络时,我可以多次重现该错误。
此外,有时大约一分钟后就会有回复。这比超时时间要长。
我已经尝试在超时后中断发出请求的线程,从而断开 HttpsURLConnection。但一定有比这更简洁的解决方案。我想知道这个无限期的超时从何而来。
有什么想法吗?
非常感谢!
最佳答案
来 self 的评论
超时时抛出的异常应该是 java.net.SocketTimeoutException
,您应该已经捕获了它,因为它不是运行时异常(但看不到您如何在代码中执行此操作)。
另请注意,API 中:
Some non-standard implmentation of this method may ignore the specified timeout. To see the connect timeout set, please call getConnectTimeout().
来自您的评论
Indeed, when I print the
getConnectTimeout()
result, I always get 0 (infinite), no matter which value I assign to it. So, we now knowHttpsURLConnection
has a "non-standard implementation" of thesetConnectTimeout()
method. But how can I restrict the infinite timeout nevertheless?
一个快速但丑陋的解决方案
- “环绕”建立连接的代码,将其移至
call
覆盖Callable<String>
(其参数化类型是我认为的result
变量的类型)。 - 从当前调用此函数的线程中,使用单线程
Executor
提交您的新Callable<String>
。 - 然后调用get关于
Future<String>
,使用您选择的超时,并处理 TimeoutException因此。
(也许)更好的长期解决方案
- 研究
abstract class HttpsURLConnection
的实现情况您正在处理的问题,看看是否存在错误/与实现它的人进行沟通。
关于java - 超时没有限制吗? - HttpsURL连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38438364/