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)

BufferedInputStream:

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)

助けてくれてありがとう、

リック

編集 私は私の答えを見つけました:

これは十分に文書化された答えではありませんでした。これは、Androidの新しいバージョンの一部に表示され、URL接続のリサイクルにバグがあります。これを修正するには(パフォーマンスの問題があるかもしれませんが)、次を追加する必要がありました。

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

ありがとう!

リック

4

4 に答える 4

42

編集する代わりに、誰かが私自身の質問に答えるように要求しました。だからここに再び答えがあります。

これは十分に文書化された答えではありませんでした。これは、Androidの新しいバージョンの一部に表示され、URL接続のリサイクルにバグがあります。これを修正するには(パフォーマンスの問題があるかもしれませんが)、次を追加する必要がありました。

if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
    urlConnect.setRequestProperty("Connection", "close");
}
于 2013-07-22T15:41:51.943 に答える
1

サーバーを指定しないため、自分で実装したカスタムサーバーである可能性があります。HTTP仕様では、応答が完全に正しくない可能性があります。

私のサーバーはpythonSimpleHTTPServerを使用していて、成功を示すために必要なのは次のことだけだと誤って想定していました。

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 pre-Froyo(2.2)には、キープアライブ接続に関連するバグがいくつかありますが、この質問には、新しいバージョンにAndroidのバグがあると主張するのに十分な情報がないと思います。

于 2015-01-08T16:34:03.167 に答える
1

まず、URLに予期しない改行('\n'または'\ r \ n')が含まれていないかどうかを確認します。含まれている場合は、応答の読み取り時にEOFExceptionが発生します。改行はHTTPパッケージをトランクし、サーバーはクライアントが送信するデータが多いと見なすため、応答がありません。応答を読み取ろうとすると、すぐにEOFが取得されます。

リクエストが有効であることを確認したら、他の人が提供するソリューションを試してください。

于 2015-01-30T09:35:16.967 に答える
0

からNetHttpTransportを使用しgoogle-api-java-clientているため、RequestPropertyの設定方法が明確ではなく、ApacheHttpTransportを使用するように切り替えたところ、問題は解決しました。

于 2014-02-07T02:38:18.747 に答える