Motivi ufficiali per "Il software ha causato l'interruzione della connessione: errore di scrittura socket"


157

Dato questo frammento di traccia dello stack

Causato da: java.net.SocketException: il software ha causato l'interruzione della connessione: errore di scrittura del socket
 su java.net.SocketOutputStream.socketWrite0 (metodo nativo)

Ho provato a rispondere alle seguenti domande:

  1. Quale codice genera questa eccezione? (JVM? / Tomcat? / Il mio codice?)
  2. Cosa provoca questa eccezione?

Per quanto riguarda il n. 1:

La fonte JVM di Sun non contiene questo messaggio esatto, ma penso che il testo Software abbia causato l'interruzione della connessione: l'errore di scrittura del socket proviene dall'implementazione nativa di SocketOutputStream:

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

Per quanto riguarda il n. 2

La mia ipotesi è che sia causato quando il client ha terminato la connessione, prima di ottenere la risposta completa (ad esempio, ha inviato una richiesta, ma prima di ottenere la risposta completa, è stato chiuso / terminato / offline)

Domande:

  1. I presupposti di cui sopra sono corretti (n. 1 e n. 2)?
  2. Questo può essere differenziato dalla situazione: "impossibile scrivere sul client, a causa di un errore di rete sul lato server "? o che renderebbe lo stesso messaggio di errore?
  3. E, cosa più importante: esiste un documento ufficiale (ad es. Di Sun) che afferma quanto sopra?

Ho bisogno di avere una prova che questa traccia dello stack è "colpa" del client socket e non c'è nulla che il server avrebbe potuto fare per evitarlo. (tranne per la cattura dell'eccezione o l'utilizzo di un SocketOutputStream non Sun JVM, sebbene entrambi non evitino realmente il fatto che il client sia terminato)


Ho questo problema quando
annullo

Ehi Eran, ricevo anche questa eccezione durante l'invio / scrittura ( outs.write(audioBytes);) byte[]in OutputStream. Quando l'audio è attivo e durante la riproduzione se l'utente fa clic su qualsiasi altro menu (che invia una richiesta del server), ho riscontrato lo stesso errore sulla console. quindi è sicuro ignorare questa eccezione?
Amogh

1
@Amogh - Sembra di sì, sì. Fondamentalmente da ciò che descrivono le risposte, si tratta di un errore specifico di Windows, ma suppongo che su Linux otterrai la stessa eccezione solo con una diversa formulazione ... (I miei laici hanno capito che è essenzialmente che ciò è causato quando invii tramite una presa in una posizione remota X e X sono stati disconnessi nel mezzo, ma sono sicuro che non è il modo più preciso per descriverlo)
Eran Medan

1
Per me questo è successo quando il server del database è stato riavviato e l'applicazione stava ancora cercando di eseguire una query utilizzando connessioni precedentemente aperte. Non sono sicuro del motivo per cui non sono stati aggiornati poiché stiamo utilizzando il pool basato su DBCP. Ma il riavvio dell'applicazione ha risolto il problema.
Kshitiz Sharma,

Risposte:


55

Questo errore può verificarsi quando il sistema di rete locale interrompe una connessione, ad esempio quando WinSock chiude una connessione stabilita dopo il fallimento della ritrasmissione dei dati (il destinatario non riconosce mai i dati inviati su un socket del datastream).

Vedi questo articolo MSDN . Vedi anche Alcune informazioni su "Il software ha causato l'interruzione della connessione" .



3
@MatGessel Quell'articolo ripete solo la confusione e ne aggiunge alcuni. WSAECONNABORTED è un codice di errore di Winsock, quindi non può esserci una spiegazione di Berkeley per questo. La situazione descritta sul server HTTP produrrebbe ECONNRESET, non WSAECONNABORTED.
Marchese di Lorne,

@EJP, Ricevo anche questa eccezione durante l'invio / scrittura (outs.write (audioBytes);) byte [] in OutputStream. Quando l'audio è attivo e durante la riproduzione se l'utente fa clic su qualsiasi altro menu (che invia una richiesta del server), ho riscontrato lo stesso errore sulla console. quindi è sicuro ignorare questa eccezione?
Amogh

1
@rustyx Tutte e tre le fonti citate qui affermano che è prodotto da guasti ACK. Se hai una fonte per il tuo reclamo, per favore, citalo.
Marchese di Lorne,

2
Questa non è una vera risposta in quanto non ti dà informazioni per perseguire ulteriormente il problema. La risposta qui è fondamentalmente "qualcosa di brutto è successo sulla rete". Sarebbe davvero utile capire quali ulteriori registri e altri registri di attività potrebbero permettermi di individuare il problema di fondo.
Derek Bennett,

11

L' java.net.SocketExceptiongenerata quando si verifica un errore di creare o accedere una presa (ad esempio TCP ). Questo di solito può essere causato quando il server ha terminato la connessione (senza chiuderla correttamente), quindi prima di ottenere la risposta completa. Nella maggior parte dei casi ciò può essere causato dal problema di timeout (ad es. La risposta richiede troppo tempo o il server è sovraccarico di richieste) o il client ha inviato il SYN, ma non ha ricevuto ACK (riconoscimento della chiusura della connessione) . Per problemi di timeout, puoi considerare di aumentare il valore di timeout.

L'eccezione socket di solito viene fornito con il messaggio di dettaglio specificato sul problema.

Esempio di messaggi dettagliati:

  • Il software ha causato l'interruzione della connessione: recv non riuscita.

    L'errore indica un tentativo di inviare il messaggio e la connessione è stata interrotta dal server. Se ciò si è verificato durante la connessione al database, ciò può essere correlato all'uso di driver JDBC Connector / J non compatibili .

    Possibile soluzione: assicurati di avere le librerie / i driver corretti nel tuo CLASSPATH.

  • Il software ha causato l'interruzione della connessione: connettersi.

    Ciò può accadere in caso di problemi con la connessione al telecomando. Ad esempio a causa del controllo antivirus che rifiuta le richieste di posta remota .

    Possibile soluzione: controllare il servizio di scansione antivirus se sta bloccando la porta per le richieste in uscita per le connessioni.

  • Il software ha causato l'interruzione della connessione: errore di scrittura del socket.

    Possibile soluzione: assicurati di scrivere la lunghezza corretta di byte nello stream. Quindi ricontrolla ciò che stai inviando. Vedi questa discussione .

  • Connessione ripristinata dal peer: errore di scrittura socket / Connessione interrotta dal peer: errore di scrittura socket

    L'applicazione non ha verificato se la connessione keep-alive era stata scaduta sul lato server.

    Possibile soluzione: assicurarsi che HttpClient sia diverso da null prima di leggere dalla connessione. E13222_01

  • Connessione ripristinata dal peer.

    La connessione è stata terminata dal peer (server).

  • Reset della connessione.

    La connessione è stata terminata dal client o chiusa dall'estremità del server della connessione a causa della richiesta con la richiesta.

    Vedi: Cosa causa il mio java.net.SocketException: connessione ripristinata?


Solo uno di questi 6 punti risponde effettivamente alla domanda, in modo errato. Anche molti altri sono errati. L'applicazione non può "verificare se la connessione keep-alive è stata scaduta sul lato server". L' HttpClientessere nullnon può causare a SocketException. Neanche scrivere la lunghezza corretta nello stream.
Marchese di Lorne,

9

L'ho visto il più delle volte quando un firewall aziendale su una workstation / laptop si intromette, uccide la connessione.

per esempio. Ho un processo server e un processo client sulla stessa macchina. Il server è in ascolto su tutte le interfacce (0.0.0.0) e il client tenta una connessione all'interfaccia pubblica / domestica (notare non l'interfaccia di loopback 127.0.0.1).

Se la macchina ha la rete disconnessa (ad es. Wifi disattivato), viene stabilita la connessione. Se la macchina è connessa alla rete aziendale (direttamente o vpn), viene formata la connessione.

Tuttavia, se la macchina è connessa a una rete Wi-Fi pubblica (o rete domestica), il firewall avvia e uccide la connessione. In questa situazione, la connessione del client all'interfaccia di loopback funziona correttamente, ma non all'interfaccia home / pubblica.

Spero che questo ti aiuti.


3
I firewall impediscono le connessioni. La domanda riguarda il ripristino di una connessione esistente.
Marchese di Lorne,

4

Per provare quale componente non funziona, monitorerei la comunicazione TCP / IP usando WireShark e vedrei chi sta chiudendo accuratamente la porta, anche i timeout potrebbero essere rilevanti.


Nessuno sta chiudendo la porta. Il sistema operativo sta interrompendo la connessione.
Marchese di Lorne,

@EJP L'ho visto accadere quando viene sovraccaricato e la memoria si esaurisce. Non sono sicuro che sia il sistema operativo a chiudere la connessione, ma JVM si scatena.
Zee,

1
@Zee C'è una differenza tra la chiusura di una porta, che è visibile come FIN in Wireshark, e l'interruzione della connessione, che non lo è.
Marchese di Lorne,

2

Hai controllato il codice sorgente Tomcat e l'origine JVM? Questo potrebbe darti più aiuto.

Penso che il tuo pensiero generale sia buono. Mi sarei aspettato uno ConnectExceptionscenario che non si potesse connettere. Quanto sopra sembra molto simile al cliente.


3
Sì, ho controllato. Le fonti di Tomcat non contenevano alcuna permutazione della frase, grazie.
Eran Medan,

1
No, non ha controllato la fonte Tomcat E la fonte JVM.
Stephen C,

O se ha controllato la fonte JVM, non ha controllato tutto.
Stephen C,

1
@Ehrann: la stringa di messaggio è molto probabilmente nelle origini native. Ma dovresti anche controllare il registro eventi. IMO, quest'ultimo è probabilmente più informativo.
Stephen C,

6
Questa stringa di messaggi proviene effettivamente dal sistema operativo.
Marchese di Lorne,

2

Per chiunque utilizzi semplici programmi Client Server e ottenga questo errore, si tratta di un problema di flussi di input o output non chiusi (o chiusi all'inizio).


2
No non lo è. Ciò comporterebbe una perdita di socket, che alla fine causerebbe un esaurimento FD.
Marchese di Lorne,

0

Stavo affrontando lo stesso problema.
Comunemente Questo tipo di errore si verifica a causa della chiusura della connessione del client e il server sta ancora tentando di scrivere su quel client.
Quindi assicurati che il tuo client abbia la connessione aperta fino a quando il server non ha terminato il suo outputstream.
E un'altra cosa, non dimenticare di chiudere il flusso di input e output.

Spero che questo ti aiuti.
E se stai ancora affrontando un problema, consulta il tuo problema qui in dettaglio.


3
@BhavinChhatrola No, una risposta errata. La situazione descritta produce "connessione reimpostata dal peer", non l'errore nella domanda.
Marchese di Lorne,

0

Questo errore mi è successo durante il test del mio servizio soap con il client SoapUI, fondamentalmente stavo cercando di ottenere un messaggio molto grande (> 500kb) e SoapUI ha chiuso la connessione per timeout.

Su SoapUI vai a:

File -> Preferenze - Timeout socket (ms)

... e metti un valore grande, come 180000 (3 minuti), questa non sarà la soluzione perfetta per il tuo problema perché il file è in realtà troppo grande, ma almeno avrai una risposta.


0

Connessione chiusa in un altro client

Nel mio caso, l'errore era:

java.net.SocketException: Software caused connection abort: recv failed

È stato ricevuto in eclipse durante il debug di un'applicazione Java che accedeva a un database H2. La fonte dell'errore era che avevo inizialmente aperto il database con SQuirreL per verificare manualmente l'integrità. Ho usato il flag per abilitare connessioni multiple allo stesso DB (es. AUTO_SERVER=TRUE), Quindi non ci sono stati problemi di connessione al DB da Java.

L'errore è apparso quando, dopo un po '- è un lungo processo Java - ho deciso di chiudere SQuirreL per liberare risorse. Sembra che SQuirreL fosse quello "proprietario" dell'istanza del server DB e che sia stato chiuso con la connessione SQuirreL.

Il riavvio dell'applicazione Java non ha prodotto nuovamente l'errore.

config

  • Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192

0

Nel mio caso, ho sviluppato il client e il lato server e ho l'eccezione:

Causa: errore di marshalling degli argomenti; l'eccezione nidificata è: java.net.SocketException: il software ha causato l'interruzione della connessione: errore di scrittura del socket

quando le classi nel client e nel server sono diverse. Non scarico le classi del server (interfacce) sul client, aggiungo solo gli stessi file nel progetto. Ma il percorso deve essere esattamente lo stesso. Ad esempio, sul progetto server ho pacchetti java \ rmi \ services con alcune interfacce di servizio e implementazioni, devo creare lo stesso pacchetto sul progetto client. Se lo cambio ad esempio con java / rmi / server / services, ottengo l'eccezione sopra. Stessa eccezione se la versione dell'interfaccia è diversa tra client e server (anche con una riga vuota aggiunta inavvertitamente ... Penso che rmi faccia una sorta di hash di classi per controllare la versione ... Non lo so ... Se potesse Aiuto ...


-1

Il mio server ha lanciato questa eccezione nel passaggio 2 giorni e l'ho risolto spostando la funzione di disconnessione con:

outputStream.close();
inputStream.close();
Client.close();

Alla fine del thread dell'elenco. se aiuterà qualcuno.


-1

Nella situazione spiegata di seguito, il lato client genererà tale eccezione:

Al server viene richiesto di autenticare il certificato client, ma il client fornisce un certificato che Uso chiave esteso non supporta l'autenticazione client, quindi il server non accetta il certificato del client e quindi chiude la connessione.


Questa risposta non è corretta Nel caso in cui descrivi verrà lanciato un SSLException.
presidente James K. Polk

in realtà lancia SocketException proprio come la domanda attuale, che avevo provato
xiaoming

-1

lato client SSL lancerà tale eccezione nella situazione di seguito (che avevo testato),:

al server viene richiesto di autenticare il certificato client, ma il client fornisce un certificato che l'utilizzo di chiavi estese non supporta l'autenticazione client.


-3

Stavo affrontando lo stesso problema con wireMock mentre deridevo le altre chiamate API. Prima stavo definendo il server in questo modo:

WireMockServer wireMockServer = null;

Ma dovrebbe essere definito come mostrato di seguito:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);

Ciò causerebbe un NullPointerException, non questo problema.
Marchese di Lorne,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.