安卓HttpsUrlConnection eofexception

40

我有一个问题,当我尝试读取任何输入时,我的HttpsURLConnection会抛出EOFException异常。这段代码可以用于某些网络调用,但在其他情况下会失败。如果我尝试从该连接中读取任何内容,它将以前面提到的错误失败。

示例:

urlConnect.getResponseCode() // will throw error
urlConnect.getResponseMessage() // will throw error
BufferedInputStream in = new BufferedInputStream(urlConnect.getInputStream()); //will throw error

以下是每个的堆栈跟踪:

getResponse:

03-14 09:49:18.547: W/System.err(6270): java.io.EOFException
03-14 09:49:18.547: W/System.err(6270):     at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:495)
03-14 09:49:18.547: W/System.err(6270):     at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)

缓冲输入流:

03-14 09:39:14.077: W/System.err(5935): java.io.EOFException
03-14 09:39:14.077: W/System.err(5935):     at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:39:14.077: W/System.err(5935):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:50:46.547: W/System.err(6476):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
03-14 09:50:46.547: W/System.err(6476):     at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

感谢任何帮助,

Rick

编辑 我找到了答案:

这不是一个文档完善的答案。在一些新版本的安卓中,出现了已回收的 URL 连接存在问题的 bug。为了解决这个问题(尽管可能会有一些性能问题),我需要添加:

if (Build.VERSION.SDK != null
&& Build.VERSION.SDK_INT > 13) {
urlConnect.setRequestProperty("Connection", "close");
}

谢谢!

Rick


1
你不需要检查Build.VERSION.SDK,因为你没有使用它。 - Lei Guo
urlConnect.setRequestProperty("Connection", "close"); urlConnect.setRequestProperty("Connection", "close"); - David Guo
它对我有效,太神奇了!感谢您的帖子。 - David Guo
你应该将你的答案作为回答添加并接受它。 - L. G.
4个回答

42

有人要求我回答自己的问题而不是编辑。所以这里再次回答。

这并不是一个很好记录的答案。在一些新版的Android中,似乎存在与回收URL连接有关的错误。为了解决这个问题(尽管可能会有一些性能问题),我需要添加:

if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
    urlConnect.setRequestProperty("Connection", "close");
}

1
这应该放在哪里? - zundi
1
如果您没有检查Build.VERSION.SDK_INT会怎样? - Vahid Ghadiri
1
还有其他什么我们可以做吗?在我的情况下设置这个头并没有帮助。 - asgs
它没有解决这个问题。EOFException仍然存在。 - nick

1
您没有指定服务器,因此可能是您自己实现的自定义服务器。您的响应可能不符合HTTP规范。
我的服务器使用Python SimpleHTTPServer,我错误地认为只需要执行以下操作即可表示成功:
self.send_response(200)

该方法发送初始响应头行、服务器和日期头,但保留流的状态,以便您能够发送其他头文件。 HTTP 要求在标头后添加一个新行以指示它们已完成。如果尝试使用 HttpURLConnection 获取结果正文 InputStream 或响应代码等时没有出现此新行,则会抛出 EOFException(考虑到这一点,实际上是合理的)。一些 HTTP 客户端确实接受了短响应并报告了成功的结果代码,这导致我可能不公平地将指责指向 HttpURLConnection。
相反,我改变了我的服务器做法(加入 Content-Length 以防万一):
self.send_response(200)
self.send_header("Content-Length", "0")
self.end_headers()

没有EOFException与该代码。这可能会触发某些服务器上的一些行为(例如,在关闭之前确保响应有效),但这不是Python SimpleHTTPServer的情况,根本原因是我的问题。
注意:Android Froyo(2.2)之前存在一些关于keep-alive连接的错误,但我认为此问题中没有足够的信息来声称新版本存在Android错误。

1
首先,检查您的URL是否包含意外的换行符('\n'或'\r\n'),如果有,则在读取响应时会收到EOFException。换行符将截断HTTP包,服务器认为客户端有更多数据要发送,因此没有响应。每次尝试读取响应都会立即得到EOF。
确保您的请求有效后,再尝试其他人提供的解决方案。

0

我使用来自google-api-java-client的NetHttpTransport,因此如何设置RequestProperty并不明显,我改用ApacheHttpTransport,问题就解决了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接