Java简单代码:java.net.SocketException:来自服务器的文件意外结束
我在Java中编写了一些简单的代码,该方法应该连接到网站并返回BufferedReader。
private BufferedReader getConnection(String url_a) { URL url; try { System.out.println("getting connection"); url = new URL(url_a); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.3) Gecko/20040924" + "Epiphany/1.4.4 (Ubuntu)"); inStream = new InputStreamReader(urlConnection.getInputStream()); return new BufferedReader(inStream); } catch (Exception ex) { Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex); } return null; }
当我在我的电脑上使用它时,它工作正常,但当我把.jar文件放在服务器上时,我收到此错误:
java.net.SocketException: Unexpected end of file from server at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:718) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579) at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:715) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322) at dataconverter.Reader.getConnection(Reader.java.260)
问题很奇怪,因为每次都不抛出exception,有时候一切正常,程序运行正常。
有没有人有任何想法?
“意外的文件结束”意味着远程服务器接受并关闭连接而不发送响应。 远程系统可能太忙而无法处理请求,或者存在随机丢弃连接的网络错误。
有了这些信息,就无法说出出了什么问题。 如果您有权访问相关服务器,则可以使用数据包嗅探工具查找确切的发送和接收内容,并查看服务器进程的日志以查看是否有任何错误消息。
概要
当您期待响应时会遇到此exception,但套接字已突然关闭。
详细说明
在这里找到的Java的HTTPClient
在非常特殊的情况下抛出一个SocketException
,消息“来自服务器的文件意外结束”。
发出请求后, HTTPClient
获取一个与请求关联的套接字绑定的InputStream
。 然后重复轮询该InputStream
,直到它:
- 查找字符串“HTTP / 1”。
- 在读取8个字符之前达到
InputStream
的结尾 - 查找“HTTP / 1”以外的字符串。
在数字2的情况下, 如果满足以下任何条件, HTTPClient
将抛出此SocketException
:
- HTTP方法是
CONNECT
- HTTP方法是
POST
,客户端设置为流模式
为什么会这样呢?
这表示在服务器能够发送响应之前TCP套接字已关闭。 这可能由于多种原因而发生,但有些可能性是:
- 网络连接丢失了
- 服务器决定关闭连接
- 客户端和服务器之间的某些东西(nginx,路由器等)终止了请求
注意:当Nginx重新加载其配置时, 它会强制关闭任何正在进行的HTTP Keep-Alive连接 (甚至是POST),从而导致此确切错误。
如果故意不提供身份validation标头或提供错误的凭据,我确实会收到此错误。
我建议使用线鲨来追踪数据包。 如果你使用的是Ubuntu,sudo-apt会收到wireshark。 就像Joni所说,找出问题的唯一方法是遵循GET请求及其相关的响应。
在我的情况下,只需将代理传递给连接即可解决。 感谢@Andreas Panagiotidis 。
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("", 80))); HttpsURLConnection con = (HttpsURLConnection) url.openConnection(proxy);
我也得到了这个例外。 我的错误代码如下
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod(requestMethod); connection.setRequestProperty("Content-type", "JSON");
我发现“Content-type”不应该是“JSON”,是错的! 我通过将此行更新到下面解决了这个exception
connection.setRequestProperty("Content-type", "application/json");
你可以查看你的“内容类型”
- HttpURLConnection即使在setDoOutput(true)之后执行get请求,setRequestMethod(“POST”)setRequestProperty(“Content”
- -POST Json with HttpUrlConnection
- 应该与CookieManager的HttpURLConnection自动处理会话cookie吗?
- HttpURLConnection getInputStream()有一秒延迟
- 如何使用HttpURLConnection在Java中等待Expect 100-continue响应
- doInBackground不更新变量
- cURL和HttpURLConnection – 发布JSON数据
- 如何使用HttpURLConnection获取重定向的URL和内容
- 用于POST请求的HttpURLConnection App Engine Java示例不起作用