HttpURLConnection getInputStream:总是在 180 秒后超时
HttpURLConnection getInputStream: timeout always after 180 seconds
我正在尝试以这种方式在非常慢的连接上下载文件:
java.net.URL url = new URL("https://X.X.X.X:8443/path/2f6b88cf2b70ee933197edfc9627a9bc/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setConnectTimeout(240 * 1000);
connection.setReadTimeout(240 * 1000);
long start = System.currentTimeMillis();
Files.copy(connection.getInputStream(), new File("test.zip").toPath());
System.out.println("Time: "+((System.currentTimeMillis() - start) / 1000) + " sec.");
我注意到由于某些原因(本机 windows 套接字超时?)它总是在下载 180 秒后中断,没有任何例外。
setConnectTimeout(...) 或 setReadTimeout(...) 中设置的超时没有帮助。
我尝试使用 wget 下载该文件:
wget https://X.X.X.X:8443/path/2f6b88cf2b70ee933197edfc9627a9bc/ --no-check-certificate
--2015-09-07 14:36:12-- https://X.X.X.X:8443/path/2f6b88cf2b70ee933197edfc9627a9bc/
Connecting to X.X.X.X:8443... connected.
WARNING: The certificate of ‘X.X.X.X’ is not trusted.
WARNING: The certificate of ‘X.X.X.X’ hasn't got a known issuer.
The certificate's owner does not match hostname ‘X.X.X.X’
HTTP request sent, awaiting response... 302 Found
Location: https://X.X.X.X:8443/files/test.zip [following]
--2015-09-07 14:36:16-- https://X.X.X.X:8443/files/test.zip
Reusing existing connection to X.X.X.X:8443.
HTTP request sent, awaiting response... 200 OK
Length: 321917584 (307M) [application/zip]
Saving to: ‘test.zip’
test.zip 100%[====================================================================================>] 307.00M 253KB/s in 19m 50ss
完整文件在 20 分钟后成功保存到磁盘上。
HttpURL连接有什么问题?
编辑:
我尝试通过 http 协议从其他服务器下载测试文件,一切正常。这似乎是服务器或协议特定的问题。但为什么 wget 设法下载整个文件?
Edit2:按照你的建议我也试过了:
- 删除connection.setDoOutput(真);
- 使用直接 link 避免重定向 302
- 通过自定义实现替换Files.copy方法
不幸的是 none 以上内容有所帮助。
编辑3:
我注意到该文件也可以通过不安全的 http 协议在同一台服务器上使用。所以我只更改了代码中的 URL,在 120 秒后我得到:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:273)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at sun.net.www.MeteredStream.read(MeteredStream.java:134)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3066)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3060)
at java.nio.file.Files.copy(Files.java:2735)
at java.nio.file.Files.copy(Files.java:2854)
connection.setRequestMethod("GET");
此处您打算执行 HTTP GET。
connection.setDoOutput(true);
此处您将其更改为 PUT。
Files.copy(connection.getInputStream(), new File("test.zip").toPath());
在这里,您无需编写任何内容即可获得输入流。服务器仍在等待您永远不会发送的 POST 数据,因此它永远不会发送响应,所以您超时了。
丢失 setDoOutput(true);
行。
我终于在这里 It is not possible to download large files at Jetty server 找到了解决方案(再次感谢 Whosebug)。问题出在服务器端。
我们使用的 Jetty 9.2 有一个错误,会中断在慢速连接上提供大文件 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=472621)。似乎并不总是抛出异常。
尽管传输停滞或连接重置,Wget 和浏览器仍能以某种方式完成下载。不幸的是,我的 Java 申请更敏感...
将捆绑的 Jetty 升级到最新的稳定版本 9.3.3 解决了所有下载问题。
我正在尝试以这种方式在非常慢的连接上下载文件:
java.net.URL url = new URL("https://X.X.X.X:8443/path/2f6b88cf2b70ee933197edfc9627a9bc/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setConnectTimeout(240 * 1000);
connection.setReadTimeout(240 * 1000);
long start = System.currentTimeMillis();
Files.copy(connection.getInputStream(), new File("test.zip").toPath());
System.out.println("Time: "+((System.currentTimeMillis() - start) / 1000) + " sec.");
我注意到由于某些原因(本机 windows 套接字超时?)它总是在下载 180 秒后中断,没有任何例外。
setConnectTimeout(...) 或 setReadTimeout(...) 中设置的超时没有帮助。
我尝试使用 wget 下载该文件:
wget https://X.X.X.X:8443/path/2f6b88cf2b70ee933197edfc9627a9bc/ --no-check-certificate
--2015-09-07 14:36:12-- https://X.X.X.X:8443/path/2f6b88cf2b70ee933197edfc9627a9bc/
Connecting to X.X.X.X:8443... connected.
WARNING: The certificate of ‘X.X.X.X’ is not trusted.
WARNING: The certificate of ‘X.X.X.X’ hasn't got a known issuer.
The certificate's owner does not match hostname ‘X.X.X.X’
HTTP request sent, awaiting response... 302 Found
Location: https://X.X.X.X:8443/files/test.zip [following]
--2015-09-07 14:36:16-- https://X.X.X.X:8443/files/test.zip
Reusing existing connection to X.X.X.X:8443.
HTTP request sent, awaiting response... 200 OK
Length: 321917584 (307M) [application/zip]
Saving to: ‘test.zip’
test.zip 100%[====================================================================================>] 307.00M 253KB/s in 19m 50ss
完整文件在 20 分钟后成功保存到磁盘上。
HttpURL连接有什么问题?
编辑: 我尝试通过 http 协议从其他服务器下载测试文件,一切正常。这似乎是服务器或协议特定的问题。但为什么 wget 设法下载整个文件?
Edit2:按照你的建议我也试过了:
- 删除connection.setDoOutput(真);
- 使用直接 link 避免重定向 302
- 通过自定义实现替换Files.copy方法
不幸的是 none 以上内容有所帮助。
编辑3: 我注意到该文件也可以通过不安全的 http 协议在同一台服务器上使用。所以我只更改了代码中的 URL,在 120 秒后我得到:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:273)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at sun.net.www.MeteredStream.read(MeteredStream.java:134)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3066)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3060)
at java.nio.file.Files.copy(Files.java:2735)
at java.nio.file.Files.copy(Files.java:2854)
connection.setRequestMethod("GET");
此处您打算执行 HTTP GET。
connection.setDoOutput(true);
此处您将其更改为 PUT。
Files.copy(connection.getInputStream(), new File("test.zip").toPath());
在这里,您无需编写任何内容即可获得输入流。服务器仍在等待您永远不会发送的 POST 数据,因此它永远不会发送响应,所以您超时了。
丢失 setDoOutput(true);
行。
我终于在这里 It is not possible to download large files at Jetty server 找到了解决方案(再次感谢 Whosebug)。问题出在服务器端。
我们使用的 Jetty 9.2 有一个错误,会中断在慢速连接上提供大文件 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=472621)。似乎并不总是抛出异常。
尽管传输停滞或连接重置,Wget 和浏览器仍能以某种方式完成下载。不幸的是,我的 Java 申请更敏感...
将捆绑的 Jetty 升级到最新的稳定版本 9.3.3 解决了所有下载问题。