web-dev-qa-db-ja.com

HttpUrlConnection.openConnectionが2回失敗する

この問題は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)

ここで何が間違っているのか誰かが考えていますか?ありがとう!

32
ggomeze

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

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());
3
ggomeze

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());
29
barrycburton

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

必要なのはconn.setRequestProperty("connection", "close");だけです

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

@fonetik、これがすでにハーモニーで発生しているかどうか知っていますか?別のhttp関連のluniの欠陥は1​​か月以上たってもまだ割り当てられていないので、それがあまり役に立たないということではありません。

24
RaB

このバグはAndroid 2.3バージョンで修正されました。System.setProperty("http.keepAlive", "false");は非常に良い解決策ではないことがわかっています。

1
allen

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

0
ZachM

Https接続を開こうとすると正常に動作しますが、2回目はHttpsURLConnection接続の代わりにシステムプロパティ値を設定したため失敗します。私はJava.io.IOException:書き込みエラー:2回目のhttps接続を開く際の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これは、必要に応じて上記のとおりです。

0
user3411924