HttpUrlConnection.openConnection завершается с ошибкой во второй раз - PullRequest
32 голосов
/ 28 июля 2010

Я знаю, что эта проблема должна быть исправлена ​​с помощью System.setProperty ("http.keepAlive", "false"); до openConnection, но это не сработало для меня. Первая попытка по этому коду работает, вторая не удалась. Даже если я попробую этот запрос менее чем через 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)

Кто-то имеет представление о том, что здесь не так? Спасибо!

Ответы [ 6 ]

29 голосов
/ 14 сентября 2010

Пул соединений, используемый 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());
24 голосов
/ 15 октября 2010

Вам не нужно System.setProperty("http.keepAlive", "false");

Все, что вам нужно, это conn.setRequestProperty("connection", "close");

, это решает проблему, но эффективно убивает сохранение в живых и, следовательно, потенциально замедляет несколько соединений (что обидно).Я искал трекер ошибок гармонии, но ничего не мог найти.

@ fonetik, знаете ли вы, что это уже поднято с гармонией?Я имею в виду, что это не очень помогает, так как еще один лунный дефект, связанный с http, все еще не назначен после более чем месяца.

3 голосов
/ 29 июля 2010

Я решил проблему. Здесь я оставляю вам код, на случай, если он кому-нибудь пригодится. В основном я вижу тенденцию в Google использовать HttpClient / HttpGet вместо HttpUrlConnection. Я попробовал эти классы, и все заработало:

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());
1 голос
/ 28 мая 2011

эта ошибка была исправлена ​​в версии Android2.3, поскольку мы знаем, что System.setProperty("http.keepAlive", "false"); не очень хорошее решение, потому что на мобильном устройстве каждое соединение создается каждый раз, когда стоит дорого.

0 голосов
/ 12 марта 2014

Когда я пытаюсь открыть https-соединение, оно работает нормально, но во второй раз не получается, потому что я установил значение системного свойства вместо HttpsURLConnection -соединения.У меня java.io.IOException: ошибка записи: проблема ввода-вывода при повторном открытии соединения https.Я использовал следующий код в моей заявке.

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);

Если вы установите системное свойство, оно будет применимо для всего приложения.Если вы хотите сбросить то же самое, вы можете следовать двумя способами.Во-первых, вы должны обновить сервер, а во-вторых, вы должны изменить HttpsURLConnection.setRequestProperty, который упоминается выше, где это необходимо.

0 голосов
/ 29 июля 2010

Я считаю, что ваша проблема заключается в порядке вашего кода.Проверьте эти методы в URLConnection JavaDocs - setRequestProperty не должен вызываться после установления соединения с mUrl.openConnection ().Это может работать в первый раз, потому что соединение установлено, тогда вы меняете настройки, которые не влияют ни на что, до следующей попытки установить соединение.Попробуйте вместо этого использовать конструктор HttpURLConnection, чтобы можно было вызывать connect () после установки свойств.

...