2010-07-28 22 views
31

Sé que este problema debería solucionarse con System.setProperty ("http.keepAlive", "false"); antes de openConnection, pero eso no funcionó para mí. Primero pruebe que este código funciona, el segundo falla. Incluso si intento esta solicitud después de menos de 5 segundos, también funciona. Si espero más que eso, vuelve a fallarHttpUrlConnection.openConnection falla la segunda vez

Este es mi código:

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

consigo la excepción en la última línea:

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) 

¿Alguien tiene una idea acerca de lo que está mal aquí ?. ¡Gracias!

Respuesta

3

He resuelto el problema. Aquí te dejo el código, en caso de que pueda ser útil para alguien. Básicamente veo una tendencia en Google para usar HttpClient/HttpGet en lugar de HttpUrlConnection. Así que traté con esas clases, y todo funcionaba:

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()); 
+10

Google ahora recomienda utilizar HttpURLConnection (a partir de pan de jengibre), ya que algunos de esos errores han sido corregidos: http: // android-developers.blogspot.com/2011/09/androids-http-clients.html –

+8

¿Por qué esta solución soluciona el problema? –

+0

Tarde o temprano, especialmente con el crecimiento de Android M, HttpClient se está depreciando. URLConnection se recomienda para aplicaciones con una larga vida por delante. – Josh

0

Creo que su problema radica en el orden de su código. Compruebe esos métodos en el URLConnection JavaDocs - setRequestProperty no se debe llamar después de que la conexión se realiza en mUrl.openConnection(). Puede estar funcionando la primera vez porque se establece la conexión, y luego está cambiando la configuración que no está afectando nada hasta la próxima vez que intente establecer una conexión. Intente utilizar el constructor HttpURLConnection en su lugar para que pueda llamar a connect() después de haber establecido las propiedades.

+1

Gracias por su respuesta, pero me temo que eso no funcionará. Esto es lo que dice el documento API: una URLConnection solo se puede configurar después de la instanciación pero antes de conectarse al recurso remoto. En mi caso la conexión real que sucede en: conn.getInputStream() y que es después de la configuración cabeceras – ggomeze

28

El grupo de conexión utilizado por HttpURLConnection cuando se mantenía con vida conexiones se rompe tal que intenta utilizar las conexiones que han sido cerradas por el servidor. De forma predeterminada, Android establece KeepAlive en todas las conexiones.

System.setProperty("http.keepAlive", "false"); es una solución que desactiva KeepAlive para todas las conexiones para que luego puedas evitar el error en la agrupación de conexiones.

conn.setRequestProperty("Connection","Keep-Alive"); activa KeepAlive para esta conexión en particular, esencialmente invirtiendo lo que System.setProperty("http.keepAlive", "false"); hace.

También siempre llamo explícitamente al connect(), ya que deja en claro dónde finaliza la configuración de la conexión. No estoy seguro si llamar a este método es opcional o no.

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()); 
+0

¡Gracias @fonetik por la respuesta y la explicación! No puedo probarlo ahora cuando me mudé a HttpClient, pero estoy seguro de que esto puede ayudar a otras personas. ¡Gracias de nuevo! – ggomeze

+0

@ user464773 'System.setProperty (" http.keepAlive "," false ");' desactiva _Keep Alive_ en todas las conexiones de la aplicación. Esto es lo que queremos porque _Keep Alive_ siempre causará errores. El uso de 'conn.setRequestProperty (" conexión "," cerrar ");' solo desactiva _Keep Alive_ para 'conn', dejando la puerta abierta para un error cuando nos olvidamos de agregarlo a una conexión. No sé si el error llegó a Harmony, pero el equipo de Android lo sabe: http://code.google.com/p/android/issues/detail?id=7786 – barrycburton

+0

Gracias, eso es justo lo que estaba buscando – TacoEater

23

usted no necesita la System.setProperty("http.keepAlive", "false");

Todo lo que necesita es conn.setRequestProperty("connection", "close");

esto soluciona el problema, pero efectivamente mata a mantener conexiones activas y por lo tanto potencialmente realiza múltiples conexiones más lentas (que es una lástima). Estaba buscando a través del rastreador de errores de armonía, pero no pude encontrar nada.

@fonetik, ¿sabes si esto ya está planteado con armonía? Quiero decir que no es que sirva de mucho ya que otro defecto de luni relacionado con http sigue sin asignarse después de más de un mes.

+0

conn.setRequestProperty ("conexión", "cerrar"); trabajó para mi. Simple y efectivo. Estoy trabajando con URLconnection para Android L y M. – Josh

1

Este error se ha corregido en la versión de Android2.3, ya que sabemos System.setProperty("http.keepAlive", "false"); no es una muy buena solución, porque en el dispositivo móvil, crear cada conexión es cada vez que es de alto costo.

0

Cuando intento abrir la conexión https, funciona bien pero la segunda vez falla porque he configurado el valor de la propiedad del sistema en lugar de la conexión HttpsURLConnection. Tengo el java.io.IOException: error de escritura: problema de E/S al abrir la conexión https por segunda vez. He usado el siguiente código en mi solicitud.

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

Pero cuando cambié el mismo a continuación, funciona bien.

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

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

Si establece la propiedad del sistema, será aplicable para toda la aplicación. Si desea restablecer lo mismo, puede seguir dos caminos. Una es que debe realizar la actualización del servidor y la segunda es cambiar el HttpsURLConnection.setRequestProperty que se menciona arriba donde sea necesario.

Cuestiones relacionadas