Error de Android: java.net.SocketException: Socket cerrado

Estoy viendo este error subir en mi accidente registra cientos de veces a la semana, pero he pasado en este punto varias semanas tratando de perseguir el error sin ningún éxito. No he podido reproducirlo en ninguno de mis dispositivos. Aquí está el rastreo de la pila:

Posix.java:-2 in "libcore.io.Posix.recvfromBytes" Posix.java:131 in "libcore.io.Posix.recvfrom" BlockGuardOs.java:164 in "libcore.io.BlockGuardOs.recvfrom" IoBridge.java:513 in "libcore.io.IoBridge.recvfrom" PlainSocketImpl.java:489 in "java.net.PlainSocketImpl.read" PlainSocketImpl.java:46 in "java.net.PlainSocketImpl.access$000" PlainSocketImpl.java:241 in "java.net.PlainSocketImpl$PlainSocketInputStream.read" AbstractSessionInputBuffer.java:103 in "org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer" AbstractSessionInputBuffer.java:191 in "org.apache.http.impl.io.AbstractSessionInputBuffer.readLine" DefaultResponseParser.java:82 in "org.apache.http.impl.conn.DefaultResponseParser.parseHead" AbstractMessageParser.java:174 in "org.apache.http.impl.io.AbstractMessageParser.parse" AbstractHttpClientConnection.java:180 in "org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader" DefaultClientConnection.java:235 in "org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader" AbstractClientConnAdapter.java:259 in "org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader" HttpRequestExecutor.java:279 in "org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse" HttpRequestExecutor.java:121 in "org.apache.http.protocol.HttpRequestExecutor.execute" DefaultRequestDirector.java:428 in "org.apache.http.impl.client.DefaultRequestDirector.execute" AbstractHttpClient.java:555 in "org.apache.http.impl.client.AbstractHttpClient.execute" AbstractHttpClient.java:487 in "org.apache.http.impl.client.AbstractHttpClient.execute" AbstractHttpClient.java:465 in "org.apache.http.impl.client.AbstractHttpClient.execute" Utilities.java:484 in "com.myapp.android.Utilities$8.run" 

Aquí está el bloque de código de donde proviene el error … el exacto donde se produce el fallo es HttpResponse response = httpclient.execute(httppost); :

  public static HttpPost postData(String URL, final List<NameValuePair> params, final Handler handler) { // Create a new HttpClient and Post Header //android.util.Log.d("Utilities", "Called postData"); final HttpClient httpclient = new DefaultHttpClient(); //httpclient. final HttpPost httppost = new HttpPost(URL); final Message msg = new Message(); final Bundle dataBundle = new Bundle(); final ByteArrayOutputStream out = new ByteArrayOutputStream(); new Thread(){ @Override public void run(){ String error = ""; String data = ""; try { httppost.setEntity(new UrlEncodedFormEntity(params)); HttpResponse response = httpclient.execute(httppost); StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == HttpStatus.SC_OK){ response.getEntity().writeTo(out); out.close(); data = out.toString(); } else{ error = EntityUtils.toString(response.getEntity()); } } catch (ClientProtocolException e) { AirbrakeNotifier.notify(e); error = e.toString(); } catch (IOException e) { AirbrakeNotifier.notify(e); error = e.toString(); } catch (Exception ex) { AirbrakeNotifier.notify(ex); error = ex.toString(); } dataBundle.putString("error", error); dataBundle.putString("data", data); msg.setData(dataBundle); handler.dispatchMessage(msg); } }.start(); return httppost; } 

¡Cualquier ayuda en finalmente calcular esto hacia fuera es muy apreciada!

En mi opinión, el culpable de este problema no es su aplicación, sino el lado remoto (es decir, el servidor HTTP). Lo más probable es que el servidor HTTP de repente está restableciendo la conexión y esto provoca una SocketException en su aplicación. En entornos de producción, estas cosas suceden con bastante frecuencia. Puede ser causada por una sobrecarga del servidor HTTP, alguna circunstancia excepcional que podría hacer que el servidor cierre (inundación de solicitud HTTP, o incluso un número incrementado de solicitudes cuando el servidor remoto se ha quedado sin recursos, el servidor también podría quedarse sin Su piscina de socket local … razones podrían ser docenas).

Si la proporción de estos errores es baja en comparación con las solicitudes HTTP satisfactorias, no me preocuparía mucho, simplemente envolvería ese código en un try { ... } catch (SocketException e) { ... } Y mostrar al usuario un cuadro de diálogo diciéndoles que la solicitud ha fallado y deben volver a intentarlo.

Lo que sin duda haría es tratar de determinar la razón de este comportamiento: intentaría coincidir con el tiempo de una de estas excepciones y tratar de cavar en los registros del servidor HTTP casi hasta ese momento para tratar de determinar la causa de este repentino Desconexión (suponiendo que tenga acceso a los registros y otras herramientas de diagnóstico). Como he dicho antes, podría ser una cosa tonta o un poco más complejo de depurar, pero yo apostaría que este es el problema.

Una excepción "java.net.SocketException: Socket closed" puede ocurrir en varias situaciones. O bien el servidor cerró la conexión como nKn sugirió, o el lado del cliente (su aplicación) cerró la conexión. Incluso si no es consciente de hacerlo, puede haber algún código menos obvio que puede conducir al cierre del socket, como Thread.interrupt () o ExecutorService.shutdownNow ().

Si por otro lado en realidad sucede en el lado del servidor, le aconsejo que implementar reintentos – 3 intentos son la práctica común y por lo general suficiente.

Actualmente está aceptando los valores predeterminados con los que está configurado el cliente lib. Tal vez quiera tomar más control de su biblioteca Httpclient especialmente en lo referente a la configuración TIMEOUT de socket. No espere a que el servidor haga algo inesperado. Establecer un tiempo de espera más corto que el predeterminado y controlar los errores de una manera que hará algún sentido a sus usuarios "Try msg msg" ….

Si u está utilizando predeterminado httpclient android, puede que desee ver alternativas que se mantienen al día con las versiones de cliente Apache más recientes …

https://hc.apache.org/httpcomponents-client-4.3.x/android-port.html

https://code.google.com/p/httpclientandroidlib/

Cliente asíncrono de fondo general

Y tenga en cuenta que con cualquiera de estos puede tener en cuenta (en Wifi) O (en 4G) que puede marcar en perfiles de tiempo de espera detallado en el que controlar los tiempos de espera con código como a continuación:

 public void create(int method, final String url, final String data) { this.method = method; this.url = url; this.data = data; if(method == GET){ this.config = RequestConfig.custom() .setConnectTimeout(6 * 1000) .setConnectionRequestTimeout(30 * 1000) .setSocketTimeout(30 * 1000) .build(); } else{ this.config = RequestConfig.custom() .setConnectTimeout(6 * 1000) .setConnectionRequestTimeout(30 * 1000) .setSocketTimeout(60 * 1000) .build(); } this.context = HttpClientContext.create(); 

Utilizando manejadores y devoluciones de llamada a la interfaz de usuario para que pueda mostrar cualquier cuadro de diálogo de alerta que desee

En runnable donde tiene el '..client.exec (request $ Type)'

  if(httprc < HttpStatus.SC_METHOD_NOT_ALLOWED){ Log.d(TAG, "entityTYP " +response.getEntity().getClass().getName()); processEntity(response.getEntity()); response.close(); }else{ Log.d(TAG, "ERR httprc " +httprc); throw new IOException("httprc " +httprc +" on " +method); } this.context.getConnection().close(); } catch (Exception e) { // this will catch your 'socketException' // catch and use the looper to direct to the desired UI thread handle handler0.sendMessage(Message.obtain(handler, HttpConnection.DID_ERROR, e.getMessage())); } 

De nuevo en el hilo de la interfaz de usuario que controla la alerta para tantos controladores de dif como u necesidad ….

  handler0 = new Handler() { public void handleMessage(Message message) { switch (message.what) { case HttpConnection.DID_START: { break; } case HttpConnection.DID_SUCCEED: { break; } case HttpConnection.DID_ERROR: { toggleSpin(false); cleanup(); //have access to orig message.obj here as well Toast.makeText(Speech_API_Activity.this, getResources().getString(R.string.heroku_msg_mux), Toast.LENGTH_SHORT).show(); break; } 

Si es necesario, puede establecer perfiles de tiempo de espera diferenciales por dominio. Toma tiempo aprender todas las cosas del constructor y las cosas del config con estos otros 2 paquetes del httpclient pero, puede valer la pena el tiempo porque usted puede fijarlo para hacer cualquier cosa que usted quiere y usted tiene control total de excepciones y de lo que usted quiere Ruta de regreso a la interfaz de usuario.

  • ¿Qué estás haciendo con HttpPost objeto devuelto por el método postData (…)? Eso puede ser una de las causas a considerar. Tenga en cuenta que hay dos hilos, un hilo principal y otro que desovas arriba.

  • En finally block necesitas cerrar recursos como httpClient y
    Respuesta, así como vaciar completamente el inputtream de respuesta. Vea ejemplos para referencia.

  • Definir explícitamente charset en UrlEncodedFormEntity, puede ser UTF-8

Trate de usar esto

 public static String WebserviceResponseHandle(String url, List<NameValuePair> namvaluePair) { String result = null; try { HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, 10000); HttpConnectionParams.setSoTimeout(httpParams, 10000); HttpClient client = new DefaultHttpClient(httpParams); HttpPost httppost = new HttpPost(url); httppost.setEntity(new UrlEncodedFormEntity(namvaluePair)); HttpResponse response = client.execute(httppost); HttpEntity entity = response.getEntity(); // If the response does not enclose an entity, there is no need if (entity != null) { InputStream instream = entity.getContent(); result = convertStreamToString(instream); } } catch (Exception e) { e.printStackTrace(); } return result; } private static String convertStreamToString(InputStream is) { /* * To convert the InputStream to String we use the * BufferedReader.readLine() method. We iterate until the BufferedReader * return null which means there's no more data to read. Each line will * appended to a StringBuilder and returned as String. */ BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 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(); } 
  • ¿Cómo puedo hacer algo cada segundo?
  • ¿Cómo comprobar si el valor ya existe en la base de datos android sqlite?
  • Android - Base de datos pre-poblada, insertada o pre-cargada?
  • Java.text.ParseException: Fecha inestable: "2014-06-04" (en el desplazamiento 5)
  • No se puede encontrar la ubicación de Android SDK para establecer la preferencia Eclipse
  • ¿Es SpannableString.setSpan () 2º parm 0-based?
  • Cómo probar la unidad android y burlarse de un método estático
  • OnSaveInstanceState no está siendo llamado en Fragment
  • ¿Hay una manera de evitar tener FullView SearchView / Keyboard en el paisaje?
  • Java ordena una matriz de meses en varios arreglos por mes
  • Donde se asigna la memoria cuando declaramos estática?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.