32

この問題はSystem.setProperty( "http.keepAlive"、 "false");で修正する必要があることを私は知っています。openConnectionの前に、しかしそれは私にはうまくいきませんでした。このコードを最初に試してみるとうまくいき、2回目は失敗します。5秒以内にこのリクエストを試しても、機能します。それ以上待つとまた失敗します

これは私のコードです:

    System.setProperty("http.keepAlive", "false");
  HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
  conn.setUseCaches(false); 
  conn.setRequestProperty("Connection","Keep-Alive"); 
  conn.setRequestProperty("User-Agent", useragent);
  conn.setConnectTimeout (30000) ; 
  conn.setDoOutput(true); 
        conn.setDoInput(true); 

  consumer.sign(conn);
  InputSource is = new InputSource(conn.getInputStream());

最後の行で例外が発生します:

java.io.IOException: Write error: I/O error during system call, Broken pipe
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativewrite(Native Method)
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.access$600(OpenSSLSocketImpl.java:55)
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:583)
W/System.err( 2164):  at java.io.OutputStream.write(OutputStream.java:82)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.sendRequest(HttpURLConnectionImpl.java:1332)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1656)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1153)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:253)

誰かがここで何が悪いのかについて考えを持っていますか?ありがとう!

4

6 に答える 6

29

HttpURLConnection接続を維持しているときに使用される接続プールが壊れているため、サーバーによって閉じられた接続を使用しようとします。デフォルトでは、Android はすべての接続で KeepAlive を設定します。

System.setProperty("http.keepAlive", "false");は、すべての接続に対して KeepAlive を無効にする回避策であるため、接続プールのバグを回避できます。

conn.setRequestProperty("Connection","Keep-Alive");この特定の接続に対して KeepAlive をオンにし、本質的に何をするかを逆にSystem.setProperty("http.keepAlive", "false");します。

connect()また、接続セットアップを終了する場所が明確になるため、常に明示的に呼び出します。このメソッドの呼び出しがオプションかどうかはわかりません。

System.setProperty("http.keepAlive", "false");
HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
conn.setUseCaches(false); 
conn.setRequestProperty("User-Agent", useragent);
conn.setConnectTimeout(30000);
conn.setDoOutput(true); 
conn.setDoInput(true); 
consumer.sign(conn);

conn.connect();

InputSource is = new InputSource(conn.getInputStream());
于 2010-09-13T20:19:14.593 に答える
24

あなたは必要ありませんSystem.setProperty("http.keepAlive", "false");

あなたに必要なのはconn.setRequestProperty("connection", "close");

これで問題は解決しますが、効果的にキープアライブを強制終了するため、複数の接続が遅くなる可能性があります (これは残念です)。ハーモニー バグ トラッカーを調べましたが、実際には何も見つかりませんでした。

@fonetik、これはすでに調和で上げられているかどうか知っていますか?別の http 関連の luni 欠陥が 1 か月以上経ってもまだ割り当てられていないため、あまり役に立たないという意味ではありません。

于 2010-10-15T15:45:27.343 に答える
3

問題を解決しました。誰かの役に立つかもしれないので、ここにコードを残しておきます。基本的に、Google では HttpUrlConnection の代わりに HttpClient/HttpGet を使用する傾向が見られます。だから私はそれらのクラスで試してみましたが、すべてうまくいきました:

final HttpClient client = new DefaultHttpClient();
final HttpGet conn = new HttpGet(mURL.toString());

OAuthConsumer consumer = mOAuthManager.getPostConsumer();
consumer.sign(conn);
HttpResponse response = client.execute(conn);
InputSource is = new InputSource(response.getEntity().getContent());
于 2010-07-29T06:43:30.037 に答える
1

このバグは Android2.3 バージョンで修正されていましたが、これSystem.setProperty("http.keepAlive", "false");はあまり良い解決策ではないことがわかっています。モバイル デバイスでは、各接続を毎回作成するのはコストがかかるためです。

于 2011-05-28T15:56:55.330 に答える
0

私はあなたの問題はあなたのコードの順序にある​​と信じています。URLConnection JavaDocsでこれらのメソッドを確認してください。mUrl.openConnection()で接続が確立された後は、setRequestPropertyを呼び出さないでください。接続が確立されているため、最初は機能している可能性があります。次に接続を試みるまで、何にも影響を与えない設定を変更しています。代わりにHttpURLConnectionコンストラクターを使用して、プロパティを設定した後にconnect()を呼び出すことができるようにしてください。

于 2010-07-29T05:40:34.323 に答える
0

https 接続を開こうとすると正常に動作しますが、HttpsURLConnection接続の代わりにシステム プロパティ値を設定したため、2 回目は失敗します。java.io.IOException: 書き込みエラー: https 接続を 2 回目に開いているときに I/O の問題が発生しました。アプリケーションで次のコードを使用しました。

System.setProperty("http.proxyHost", proxy);
System.setProperty("http.proxyPort", port);

しかし、同じものを以下に変更すると、正常に動作します。

javax.net.ssl.HttpsURLConnection ucon = (javax.net.ssl.HttpsURLConnection) urlWPF.openConnection(proxyserver);

ucon.setRequestProperty("http.proxyHost", proxy);
ucon.setRequestProperty("http.proxyPort", port);

システム プロパティを設定すると、アプリケーション全体に適用されます。同じものをリセットしたい場合は、2 つの方法に従うことができます。1 つはサーバーを更新する必要があること、2 つ目はHttpsURLConnection.setRequestProperty必要に応じて上記の内容を変更する必要があることです。

于 2014-03-12T17:38:28.403 に答える