2008-09-15 27 views
80

Estoy recibiendo el siguiente error al intentar leer desde un socket. Estoy haciendo un readInt() en ese InputStream, y estoy obteniendo este error. Al examinar la documentación, esto sugiere que la parte del cliente de la conexión cerró la conexión. En este escenario, yo soy el servidor.java.net.SocketException: Connection reset

Tengo acceso a los archivos de registro del cliente y no está cerrando la conexión, y de hecho sus archivos de registro sugieren que estoy cerrando la conexión. Entonces, ¿alguien tiene una idea de por qué está sucediendo esto? ¿Qué más debo verificar? ¿Surge esto cuando hay recursos locales que quizás están llegando a los umbrales?


me cuenta que tengo la siguiente línea:

socket.setSoTimeout(10000); 

justo antes de la readInt(). Hay una razón para esto (larga historia), pero solo curiosidad, ¿hay circunstancias bajo las cuales esto podría llevar al error indicado? Tengo el servidor ejecutándose en mi IDE, y dejé mi IDE atascado en un punto de interrupción, y entonces noté que los mismos errores exactos comienzan a aparecer en mis propios registros en mi IDE.

De todos modos, solo mencionarlo, espero que no sea una pista falsa. :-(

+0

¿Tiene usted trazas de la pila de ambos lados? ¿Puedes describir la arquitectura de la red un poco más? (¿Por Internet salvaje? ¿En la misma máquina? ¿En algún lugar intermedio?) ¿Sucede todo el tiempo? O intermitentemente? –

Respuesta

8

Siempre que he tenido problemas impares como éste, por lo general siento con una herramienta como WireShark y mirar los datos en bruto que se pasaron un lado a otro. Puede que se sorprenda cuando se desconectan las cosas, y que está Sólo se notificó cuando intenta y leer.

31

restablecimiento de la conexión, simplemente significa que un TCP RST fue recibido. Esto sucede cuando al otro ordenador recibe los datos que no puede procesar, y no puede haber varias razones para ello.

Lo más simple es cuando cierra el socket y luego escribe más datos en la secuencia de salida. Al cerrar el socket, le dijo a su igual que has terminado de hablar, y puede olvidarse de tu conexión. Cuando envía más datos en esa secuencia de todos modos, el par lo rechaza con un RST para hacerle saber que no está escuchando.

En otros casos, un cortafuegos intermedio o incluso el propio host remoto podrían "olvidarse" de su conexión TCP. Esto podría suceder si no envía datos por un tiempo prolongado (2 horas es un tiempo de espera común), o porque el par fue reiniciado y perdió su información sobre las conexiones activas. El envío de datos en una de estas conexiones difuntas también provocará un RST.


actualización en respuesta a la información adicional:

Tome un vistazo de cerca a su manejo de la SocketTimeoutException. Esta excepción se plantea si se excede el tiempo de espera configurado mientras está bloqueado en una operación de socket. El estado del zócalo en sí no cambia cuando se lanza esta excepción, pero si su manejador de excepciones cierra el zócalo y luego intenta escribir en él, estará en una condición de restablecimiento de la conexión. setSoTimeout() está diseñado para darle una forma limpia de salir de una operación read() que de lo contrario podría bloquear para siempre, sin hacer cosas sucias como cerrar el socket de otro hilo.

+0

No es correcto en varios aspectos. La recolección de basura y las salidas de proceso causan cierres adecuados, no reinicios, pero un cierre seguido de una escritura por parte del par puede inducir un restablecimiento en lugar de un EOS. SocketTimeoutExceptions solo se generan si el lector ha establecido un tiempo de espera de lectura. – EJP

+0

Y no siempre significa que se recibió un RST. También puede significar que uno fue generado por este lado. – EJP

+3

EJP todavía salado 5 años después? – Daedric

81

Existen varias causas posibles.

  1. El otro extremo ha restablecido deliberadamente la conexión, de una forma que no documentaré aquí. Es raro, y generalmente incorrecto, que el software de aplicación lo haga, pero no es desconocido para un software comercial.

  2. Más comúnmente, se produce al escribir en una conexión que el otro extremo ya se ha cerrado normalmente. En otras palabras, un error de protocolo de aplicación.

  3. También puede ser causado por el cierre de un zócalo cuando hay datos no leídos en el búfer de recepción de zócalo.

  4. En Windows, 'el software provocó la interrupción de la conexión', que no es lo mismo que 'restablecimiento de conexión', es causado por el envío de problemas de red desde su extremo. Hay un artículo de la base de conocimiento de Microsoft sobre esto.

+1

FYI http://support.microsoft.com/kb/204594 –

+0

@MattLyons Gracias. Hay mucho mejores artículos de MSDN que eso. Francamente, me resulta difícil de creer. Una conexión ni siquiera existirá hasta que se hayan establecido las direcciones IP de origen y destino correctas. Los artículos de MSDN que he visto se refieren a errores persistentes de la red que interrumpen la conexión. – EJP

3

Tuve el mismo error. Encontré la solución para el problema ahora. El problema era que el programa del cliente estaba terminando antes de que el servidor leyera las transmisiones.

+0

Eso no causaría esta excepción por sí mismo. – EJP

+0

sería si System.exit (0) cancela el programa y nadie llama a socket.close() ya que la conexión está en mal estado y no se cerró correctamente. muuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu –

+0

@ DeanHiller No, no lo haría. El sistema operativo cerraría el socket de la misma manera que la aplicación debería tener. – EJP

5

Es embarazoso decirlo, pero cuando tuve este problema, fue simplemente un error que cerré la conexión antes de leer todos los datos. En los casos en que se devolvieron pequeñas cadenas, funcionó, pero eso probablemente se debió a que toda la respuesta se almacenó en un búfer, antes de que lo cerrara.

En los casos en que se devolvieron cantidades de texto más largas, se lanzó la excepción, ya que había más de un buffer volviendo.

Puede verificar este descuido. Recuerde que abrir una URL es como un archivo, asegúrese de cerrarla (liberar la conexión) una vez que se haya leído por completo.

1

También tuve este problema con un programa Java que intenta enviar un comando en un servidor a través de SSH. El problema fue con la máquina ejecutando el código de Java. No tenía el permiso para conectarse al servidor remoto. El método write() funcionaba bien, pero el método read() arrojaba java.net.SocketException: restablecimiento de la conexión. Solucioné este problema añadiendo la clave SSH del cliente a las claves conocidas del servidor remoto.

2

Tuve este problema con un sistema SOA escrito en Java. Estaba ejecutando tanto el cliente como el servidor en diferentes máquinas físicas y funcionaron bien durante mucho tiempo, luego esos desagradables restablecimientos de conexión aparecieron en el registro del cliente y no había nada extraño en el registro del servidor. Reiniciar el cliente y el servidor no resolvió el problema. Finalmente descubrimos que el montón en el lado del servidor estaba bastante lleno, así que aumentamos la memoria disponible para la JVM: ¡problema resuelto! Tenga en cuenta que no había OutOfMemoryError en el registro: la memoria era escasa, no estaba agotada.

5

Debe inspeccionar traza completa con mucho cuidado,

tengo una aplicación de socket del servidor y se fija un caso java.net.SocketException: Connection reset.

En mi caso ocurre mientras se lee desde un objeto Socket cliente que cerró su conexión por algún motivo. (Red perdida, cortafuegos o caída de la aplicación o cierre previsto)

En realidad estaba restableciendo la conexión cuando recibí un error al leer este objeto Socket.

Socket clientSocket = ServerSocket.accept(); 
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
int readed = is.read(); // WHERE ERROR STARTS !!! 

Lo interesante es for my JAVA Socket si un cliente se conecta a mi ServerSocket y cerrar su conexión sin enviar nada is.read() llama a sí mismo, porque parece recursively.It de estar en un bucle while para leer desde este conector intenta leer de una conexión cerrada. Si utiliza algo como a continuación para la operación de lectura;

while(true) 
{ 
    Receive(); 
} 

A continuación, se obtiene una algo StackTrace como el de abajo y sigue

java.net.SocketException: Socket is closed 
    at java.net.ServerSocket.accept(ServerSocket.java:494) 

Lo que sí está cerrando ServerSocket y la renovación de mi conexión a la espera de nuevas conexiones de cliente entrantes

String Receive() throws Exception 
{ 
try {     
      int readed = is.read(); 
      .... 
}catch(Exception e) 
{ 
     tryReConnect(); 
     logit(); //etc 
} 


//... 
} 

Esto reestabliza mi conexión para los clientes desconocidos socket pierde

private void tryReConnect() 
     { 
      try 
      { 
       ServerSocket.close(); 
       //empty my old lost connection and let it get by garbage col. immediately 
       clientSocket=null; 
       System.gc(); 
       //Wait a new client Socket connection and address this to my local variable 
       clientSocket= ServerSocket.accept(); // Waiting for another Connection 
       System.out.println("Connection established..."); 
      }catch (Exception e) { 
       String message="ReConnect not successful "+e.getMessage(); 
       logit();//etc... 
      } 
     } 

No pude encontrar otra manera porque como puede ver en la imagen de abajo no puede entender si la conexión se pierde o no sin un try and catch, porque todo parece correcto. Obtuve esta instantánea mientras obtenía Connection reset continuamente.

enter image description here