我用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;
}
当我在PC上使用它时,它可以正常工作,但是当我.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)
问题很奇怪,因为不是每次都抛出异常,有时一切正常,程序运行正常。
有人有什么想法吗?
意外的文件结束"表示远程服务器接受并关闭了连接而不发送响应。可能是远程系统太忙而无法处理请求,或者存在随机断开连接的网络错误。
服务器中也可能存在错误:请求中的某些内容导致内部错误,服务器只是关闭连接,而不是像它应该的那样发送HTTP错误响应。有几个人认为这是由于请求中缺少标头或标头值无效引起的。
有了可用的信息,就不可能说出了什么问题。如果您有权访问有问题的服务器,则可以使用数据包嗅探工具来查找发送和接收的确切内容,并查看服务器进程的日志以查看是否有任何错误消息。
总结
当您期望收到响应,但套接字突然关闭时,会遇到此异常。
详细解释
在这里找到的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),从而导致此确切错误。
当我没有设置身份验证标头或设置错误的凭据时,我确实会收到此错误。
就我而言,只需将代理传递给连接即可解决。感谢@Andreas Panagiotidis。
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("<YOUR.HOST>", 80)));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection(proxy);
我建议使用wire shark来跟踪数据包。如果你使用的是 Ubuntu,sudo-apt get wireshark。就像 Joni 所说,找出问题所在的唯一方法是遵循 GET 请求及其相关响应。
http://www.wireshark.org/download.html
在我的情况下,url 包含错误的字符,如空格。总体记录您的网址,在某些情况下使用浏览器。
您设置的标头很可能不正确或不可接受的。
例:
connnection.setRequestProperty("content-type", "application/json");
我也得到了这个例外。我的错误代码如下
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(requestMethod);
connection.setRequestProperty("Content-type", "JSON");
我发现"内容类型"不应该是"JSON",是错误的!我通过将这一行更新到下面解决了这个异常
connection.setRequestProperty("Content-type", "application/json");
您可以检查您的"内容类型"