it-swarm.it

java.net.SocketException: connessione ripristinata

Sto ottenendo il seguente errore cercando di leggere da un socket. Sto facendo un readInt() su quel InputStream, e sto ricevendo questo errore. Leggendo la documentazione questo suggerisce che la parte client della connessione ha chiuso la connessione. In questo scenario, sono il server.

Ho accesso ai file di registro del client e non sta chiudendo la connessione, e in effetti i suoi file di registro suggeriscono che sto chiudendo la connessione. Quindi qualcuno ha un'idea del perché questo sta accadendo? Cos'altro per verificare? Ciò sorge quando ci sono risorse locali che stanno forse raggiungendo le soglie?


Prendo atto che ho la seguente riga:

socket.setSoTimeout(10000);

appena prima della readInt(). C'è una ragione per questa (lunga storia), ma solo curiosità, ci sono circostanze in cui ciò potrebbe portare all'errore indicato? Ho il server in esecuzione nel mio IDE e mi è capitato di lasciare il mio IDE bloccato su un punto di interruzione, e ho poi notato che gli stessi identici errori iniziano a comparire nei miei log nel mio IDE.

Ad ogni modo, solo menzionandolo, si spera non sia una falsa pista. :-(

101
Darryl

Ci sono diverse possibili cause.

  1. L'altro capo ha deliberatamente ripristinato la connessione, in un modo che non documenterò qui. È raro, e generalmente scorretto, che il software applicativo faccia questo, ma non è sconosciuto per il software commerciale.

  2. Più comunemente, è causato dalla scrittura su una connessione che l'altra estremità ha già chiuso normalmente. In altre parole, un errore del protocollo dell'applicazione.

  3. Può anche essere causato chiudendo un socket quando ci sono dati non letti nel buffer di ricezione socket.

  4. In Windows, "il software ha causato l'interruzione della connessione", che non è lo stesso di "ripristino della connessione", è causato dall'invio di problemi di rete da parte dell'utente. C'è un articolo della Microsoft Knowledge Base su questo.

100
user207421

Il reset della connessione significa semplicemente che è stato ricevuto un TCP RST. Ciò accade quando il tuo peer riceve dati che non può elaborare e possono esserci vari motivi.

Il più semplice è quando si chiude il socket e quindi si scrivono più dati sul flusso di output. Chiudendo la presa, hai detto al tuo pari che hai finito di parlare e che può dimenticare la tua connessione. Quando si inviano comunque più dati su quel flusso, il peer lo rifiuta con un RST per informarlo che non sta ascoltando.

In altri casi, un firewall intervenuto o persino l'host remoto potrebbe "dimenticare" la connessione TCP. Ciò potrebbe accadere se non si invia alcun dato per un lungo periodo di tempo (2 ore è un timeout comune), o perché il peer è stato riavviato e ha perso le sue informazioni sulle connessioni attive. L'invio di dati su una di queste connessioni defunte causerà anche un RST.


Aggiornamento in risposta a ulteriori informazioni:

Osserva da vicino la gestione di SocketTimeoutException. Questa eccezione viene sollevata se il timeout configurato viene superato mentre è bloccato su un'operazione socket. Lo stato del socket stesso non viene modificato quando viene generata questa eccezione, ma se il gestore delle eccezioni chiude il socket e quindi prova a scrivere su di esso, ci si troverà in una condizione di ripristino della connessione. setSoTimeout() ha lo scopo di darti un modo pulito per uscire da un'operazione read() che potrebbe altrimenti bloccare per sempre, senza fare cose sporche come chiudere il socket da un altro thread.

41
erickson

Ogni volta che ho avuto problemi strani come questo, di solito mi siedo con uno strumento come WireShark e guardo i dati grezzi che vengono passati avanti e indietro. Potresti rimanere sorpreso quando le cose vengono disconnesse e sei solo notificato quando provi e leggi.

13
GEOCHET

Imbarazzante dirlo, ma quando ho avuto questo problema, è stato semplicemente un errore che stavo chiudendo la connessione prima di leggere tutti i dati. In caso di restituzione di stringhe di piccole dimensioni, ha funzionato, ma probabilmente a causa dell'intera risposta è stato memorizzato il buffer, prima di chiuderlo.

In caso di quantità di testo più lunghe che venivano restituite, veniva lanciata l'eccezione, poiché più di un buffer stava tornando indietro.

Potresti controllare questa svista. Ricorda che aprire un URL è come un file, assicurati di chiuderlo (rilascia la connessione) una volta che è stato letto completamente.

8
Scott S

Dovresti ispezionare la traccia completa con molta attenzione,

Ho un'applicazione server socket e ho risolto un caso Java.net.SocketException: Connection reset.

Nel mio caso capita durante la lettura da un oggetto client Socket che ha chiuso la sua connessione per qualche motivo. (Rete persa, firewall o crash dell'applicazione o chiusura prevista)

In realtà stavo ristabilendo la connessione quando ho ricevuto un errore durante la lettura da questo oggetto Socket.

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

La cosa interessante è for my Java Socket se un client si connette alla mia ServerSocket e chiude la sua connessione senza inviare nulla is.read() si chiama in modo ricorsivo. Sembra che stando in un ciclo infinito per la lettura da questo socket provi a leggere da una connessione chiusa. Se si utilizza qualcosa come sotto per l'operazione di lettura;

while(true)
{
  Receive();
}

Quindi ottieni uno stackTrace qualcosa di simile in avanti e avanti

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

Quello che ho fatto è solo chiudere ServerSocket e rinnovare la mia connessione e attendere ulteriori connessioni client in entrata

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


//...
}

Ciò ristabilisce la mia connessione per gli errori di socket client sconosciuti

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...
            }
        }

Non sono riuscito a trovare un altro modo perché, come vedi dall'immagine qui sotto, non puoi capire se la connessione è persa o meno senza un try and catch, perché tutto sembra giusto. Ho ottenuto questa istantanea mentre stavo ottenendo Connection reset continuamente.

enter image description here

7
Davut Gürbüz

Ho avuto lo stesso errore. Ho trovato la soluzione per il problema ora. Il problema era che il programma client stava terminando prima che il server leggesse i flussi.

5
kml_ckr

Ho avuto questo problema con un sistema SOA scritto in Java. Stavo eseguendo sia il client che il server su macchine fisiche diverse e hanno funzionato bene per un lungo periodo, poi quelle brutte reimpostazioni di connessione sono apparse nel registro del client e non c'era nulla di strano nel registro del server. Il riavvio del client e del server non ha risolto il problema. Alla fine abbiamo scoperto che l'heap sul lato server era piuttosto pieno, quindi abbiamo aumentato la memoria disponibile per la JVM: problema risolto! Si noti che non c'era OutOfMemoryError nel registro: la memoria era scarsa, non esaurita.

4
Pino

Ho anche avuto questo problema con un programma Java cercando di inviare un comando su un server tramite SSH. Il problema era con la macchina che eseguiva il codice Java. Non aveva il permesso di connettersi al server remoto. Il metodo write () stava andando bene, ma il metodo read () stava lanciando un Java.net.SocketException: Connection reset. Ho risolto questo problema aggiungendo la chiave SSH del client alle chiavi conosciute del server remoto.

1
pmartin8