web-development-kb-es.site

java.net.SocketException: restablecimiento de la conexión

Recibo el siguiente error al intentar leer desde un socket. Estoy haciendo una readInt() en esa InputStream, y estoy recibiendo este error. Examinando 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.

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é sucede esto? ¿Qué más hay que comprobar? ¿Surge esto cuando hay recursos locales que quizás están alcanzando los umbrales?


Tengo en 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 por curiosidad, ¿existen 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 luego noté que los mismos errores comienzan a aparecer en mis propios registros en mi IDE.

De todos modos, solo mencionándolo, ojalá no sea una pista falsa. :-(

101
Darryl

Hay varias causas posibles.

  1. El otro extremo ha restablecido deliberadamente la conexión, de una manera que no documentaré aquí. Es raro, y generalmente incorrecto, que el software de la aplicación haga esto, pero no es desconocido para el 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 producirse cerrando un socket cuando hay datos sin leer en el buffer de recepción de socket.

  4. En Windows, "el software provocó el aborto de la conexión", que no es lo mismo que el "restablecimiento de la conexión", se debe a problemas de red que se envían desde su extremo. Hay un artículo de Microsoft Knowledge Base sobre esto.

100
user207421

El restablecimiento de la conexión simplemente significa que se recibió un TCP RST. Esto sucede cuando su par recibe datos que no puede procesar, y puede haber varias razones para ello.

Lo más sencillo es cuando cierra el zócalo y luego escribe más datos en la secuencia de salida. Al cerrar el zócalo, le dijo a su compañero que ha terminado de hablar y que puede olvidarse de su conexión. De todos modos, cuando envía más datos en ese flujo, el interlocutor lo rechaza con un RST para hacerle saber que no está escuchando.

En otros casos, un servidor de seguridad intermedio o incluso el propio Host remoto podrían "olvidar" su conexión TCP. Esto podría suceder si no envía datos durante un tiempo prolongado (2 horas es un tiempo de espera común), o porque el par se reinició y perdió su información sobre las conexiones activas. Enviar datos en una de estas conexiones inactivas también causará un RST.


Actualización en respuesta a información adicional:

Eche un vistazo de cerca a su manejo de la SocketTimeoutException. Esta excepción se produce 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 administrador 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á destinado a brindarle una forma limpia de salir de una operación read() que de otra manera podría bloquear para siempre, sin hacer cosas sucias, como cerrar el socket desde otro hilo.

41
erickson

Siempre que he tenido problemas extraños como este, normalmente me siento con una herramienta como WireShark y veo los datos en bruto que se están pasando de un lado a otro. Es posible que se sorprenda de dónde se desconectan las cosas y solo está siendo notificado cuando intenta leer.

13
GEOCHET

Avergonzado de decirlo, pero cuando tuve este problema, fue simplemente un error el hecho de cerrar la conexión antes de leer todos los datos. En los casos en que se devolvieron cadenas pequeñas, funcionó, pero eso probablemente se debió a que toda la respuesta fue amortiguada, antes de que la cerrara.

En los casos en que se devuelve una mayor cantidad de texto, se lanza la excepción, ya que más de un búfer regresaba.

Usted podría comprobar esta supervisión. Recuerde que abrir una URL es como un archivo, asegúrese de cerrarla (liberar la conexión) una vez que se haya leído completamente.

8
Scott S

Usted debe inspeccionar el rastro completo con mucho cuidado,

Tengo una aplicación de socket de servidor y arreglé un caso Java.net.SocketException: Connection reset.

En mi caso, sucede mientras se lee desde un objeto clientSocket Socket que se cierra su conexión debido a algún motivo. (Red perdida, firewall o falla de aplicación o cierre intencional)

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 cierra su conexión sin enviar nada is.read() se llama a sí mismo de forma recursiva. Parece que al estar en un bucle infinito para leer desde este socket, intenta leer desde una conexión cerrada. Si usa algo como abajo para la operación de lectura;

while(true)
{
  Receive();
}

Entonces obtienes un stackTrace algo como abajo una y otra vez

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

Lo que hice fue simplemente cerrar ServerSocket, renovar mi conexión y esperar más conexiones de clientes entrantes

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


//...
}

Esto restablece mi conexión para pérdidas de socket de cliente desconocido

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 forma porque, como se puede ver en la imagen de abajo, no se puede entender si la conexión se pierde o no sin un try and catch, porque todo parece correcto. Obtuve esta instantánea mientras recibía Connection reset continuamente.

 enter image description here 

7
Davut Gürbüz

Yo tenía el mismo error. He encontrado la solución para el problema ahora. El problema era que el programa cliente estaba terminando antes de que el servidor leyera las secuencias.

5
kml_ckr

Tuve este problema con un SOA sistema escrito en Java. Estaba ejecutando el cliente y 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 solucionó el problema. Finalmente, descubrimos que el montón en el lado del servidor estaba bastante lleno, por lo que aumentamos la memoria disponible para la JVM: ¡problema resuelto! Tenga en cuenta que no había un error OutOfMemory en el registro: la memoria era escasa, no estaba agotada.

4
Pino

También tuve este problema con un programa Java que intentaba enviar un comando en un servidor a través de SSH. El problema era que la máquina ejecutaba el código Java. No tenía permiso para conectarse al servidor remoto. El método write () estaba funcionando bien, pero el método read () lanzaba una excepción Java.net.SocketException: restablecimiento de la conexión. Solucioné este problema con la adición de la clave SSH del cliente a las claves conocidas del servidor remoto.

1
pmartin8