15

これが最も簡単な方法での質問です。

HttpUrlConnection オブジェクトを使用して、プロキシ経由でサーバーへの HTTPS 接続を作成します。

プロキシは接続を閉じますが、コードは同じ接続を再利用しようとします。そして、EOFExceptionが発生します。

このような場合はどのように処理すればよいですか?

4

12 に答える 12

9

http.keepalive システム プロパティを無効にすることをお勧めします。ドキュメントのパフォーマンス セクションには、可能な場合はソケット接続が再利用されることが示されています。接続を再利用しようとしているように見えますが、プロキシは既に接続を閉じています。この投稿で、Darrell は、システム プロパティを変更することで問題が解決したことも示しています。

System.setProperty("http.keepAlive", "false");
于 2012-09-11T20:22:14.807 に答える
6

1月8日にAndroidでこの問題が修正されたことが判明しました[1]。この修正により、基本的に古い接続がリサイクルされたものとしてマークされ、内部でリクエストが再試行されます。

今のところこれを修正するには、スタックオーバーローを防ぐために再試行制限でEOFExceptionが発生した場合に、要求を再試行することをお勧めします。

  1. https://android.googlesource.com/platform/libcore/+/19aa40c81c48ff98ccc7272f2a3c41479b806376
于 2013-02-18T23:59:20.260 に答える
4

通常の HTTP 接続でもこの問題が発生しました。最初のリクエストは成功しましたが、2 番目のリクエストは EOFException で失敗しました。

結局、削除して修正しました...

urlConnection.setChunkedStreamingMode(0);

...HttpUrlConnection から。

私が呼び出している Web サーバーは、チャンクされたデータをうまく処理できない可能性があります。わからない。

于 2012-11-28T13:02:58.090 に答える
1

接続を再利用したくない場合は、解放してください。

finally {
     urlConnection.disconnect();
   }

于 2012-09-16T06:44:07.627 に答える
0

同じ HttpURLConnection インスタンスを再利用しようとするべきではありません。「クラスの概要」の一番下の行にあるドキュメントは言う

HttpURLConnection の各インスタンスは、1 つの要求/応答ペアに使用できます。

Keep-Alive 接続は別のレベルで機能します。切断に関するドキュメントを参照してください: http://developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()

他の Java 実装とは異なり、再利用可能なソケット接続が閉じられるとは限りません。HTTP 要求を発行する前に、http.keepAlive システム プロパティを false に設定することにより、すべての接続の再利用を無効にすることができます。

したがって、常に新しい HttpURLConnection を使用し、ソケット プール ハンドルを再利用できるようにする必要があります。サーバーによって閉じられたソケットを再利用しようとすると、問題が発生する可能性があります。これについては、この質問への回答で対処します: Android HttpUrlConnection EOFException

Froyo (2.2) より前のキープアライブ接続には明らかにバグがあったため、これらの古いデバイスではキープアライブを無効にすることをお勧めします。

私の場合、サーバーが完全な応答を送信しなかったために EOFException が発生しました。詳細については、https ://stackoverflow.com/a/27845939/2335025 を参照してください。

于 2015-01-08T18:04:57.420 に答える
0

このメソッドを使用してサーバーからデータを取得し、入力トリムを文字列に変換してから、さらに使用するために解析できます。

  public static InputStream getUrlData(final String url)
        throws URISyntaxException, ClientProtocolException, IOException {
    final DefaultHttpClient client = new DefaultHttpClient();
    final HttpGet method = new HttpGet(new URI(url));
    final HttpResponse res = client.execute(method);
    return res.getEntity().getContent();
    }
于 2012-09-16T15:56:21.547 に答える
0

同じ HttpURLConnection インスタンスを再利用しようとするべきではありません。「クラスの概要」の一番下の行にあるドキュメントは言う

HttpURLConnection の各インスタンスは、1 つの要求/応答ペアに使用できます。

Keep-Alive 接続は異なるレベルで機能します。切断に関するドキュメントを参照してください: http://developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()

他の Java 実装とは異なり、再利用可能なソケット接続が閉じられるとは限りません。HTTP 要求を発行する前に、http.keepAlive システム プロパティを false に設定することにより、すべての接続の再利用を無効にすることができます。

したがって、常に新しい HttpURLConnection を使用し、ソケット プール ハンドルを再利用できるようにする必要があります。

Froyo (2.2) より前のキープアライブ接続には明らかにバグがあったため、これらの古いデバイスではキープアライブを無効にすることをお勧めします。

私の場合、サーバーが完全な応答を送信しなかったことが EOFException の原因でした。詳細については、https ://stackoverflow.com/a/27845172/2335025 を参照してください。

于 2015-01-08T16:59:35.790 に答える
0

おそらくhttpClient「バグが多く」、非推奨ですが、JellyBean のこの問題は大きな問題です。私はKsoap2を使用しているので、提案されたすべての回答を試しました。

  • System.setProperty("http.keepAlive", "false");
  • httpTransportSE.getServiceConnection().setRequestProperty("Connection", "close");
  • httpTransportSE.getServiceConnection().disconnect();

何も機能しませんでした - 私の解決策は、使用している Ksoap2 のバージョンを 3.1.1 から 2.6.5 にロールバックすることでした。2.6.5 を使用すると、この問題は大幅に軽減されます。まだテスト中ですが、おそらく解決することさえあります。

于 2014-01-15T02:42:53.470 に答える
-1

このコードを試してください:`

Httppost メソッド:

    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
    HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
    HttpClient client = new DefaultHttpClient(httpParams);
    HttpPost request = new HttpPost("put_url");
    request.setHeader("Content-Type", "application/xml");

    String file = resourceXml();


    StringEntity se = null;
    try {
        se = new StringEntity(file);
    } catch (UnsupportedEncodingException e1) {

        e1.printStackTrace();
    }

    se.setContentEncoding("UTF-8");
    se.setContentType("application/xml");
    request.setEntity(se);
    HttpResponse response = null;
    try {
        response = client.execute(request);
    } catch (ClientProtocolException e1) {

        e1.printStackTrace();
    } catch (IOException e1) {

        e1.printStackTrace();
    }

    HttpEntity entity = response.getEntity();
    InputStream is = null;
    try {
        is = entity.getContent();
    } catch (IllegalStateException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    }
    String _response = convertStreamToString(is);

    Log.i(TAG, "Response:" + _response);
    // Check if server response is valid code
    int res_code = response.getStatusLine().getStatusCode();
    Log.i(TAG, "status_code" + res_code);
    try {
        is.close();
    } catch (IOException e) {

        e.printStackTrace();
    }

`

于 2012-09-07T13:51:59.793 に答える
-1

ストリームを文字列に変換するには:`

private static String convertStreamToString(InputStream is) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(is),
            8192);
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append((line + "\n"));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();

}`
于 2012-09-07T14:03:27.737 に答える