java.net.SocketException: Resetarea conexiunii

Primesc următoarea eroare când încerc să citesc de pe un socket. Fac un readInt() pe acel InputStream și primesc această eroare. Răsfoind documentația, acest lucru sugerează că partea client a conexiunii a închis conexiunea. În acest scenariu, eu sunt serverul.

Am acces la fișierele de jurnal ale clientului și acesta nu închide conexiunea și, de fapt, fișierele sale de jurnal sugerează că eu închid conexiunea. Are cineva o idee de ce se întâmplă acest lucru? Ce altceva trebuie să verificăm? Apare acest lucru atunci când există resurse locale care poate ating praguri?


Observ că am următoarea linie:

socket.setSoTimeout(10000);

chiar înainte de readInt(). Există un motiv pentru acest lucru (poveste lungă), dar, din curiozitate, există circumstanțe în care acest lucru ar putea duce la eroarea indicată? Am serverul care rulează în IDE-ul meu și s-a întâmplat să las IDE-ul meu blocat pe un punct de întrerupere, iar apoi am observat că exact aceleași erori au început să apară în jurnalele mele din IDE.

Oricum, doar am menționat-o, sper să nu fie o pistă roșie :-(

Există mai multe cauze posibile.

  1. Celălalt capăt a resetat în mod deliberat conexiunea, într-un mod pe care nu îl voi documenta aici. Este rar și, în general, incorect ca un software de aplicație să facă acest lucru, dar nu este necunoscut pentru software-ul comercial.

  2. Mai frecvent, este cauzată de scrierea pe o conexiune pe care celălalt capăt a închis-o deja în mod normal. Cu alte cuvinte, o eroare de protocol al aplicației.

  3. De asemenea, poate fi cauzată de închiderea unui socket atunci când există date necitite în bufferul de recepție al socketului.

  4. În Windows, 'software caused connection abort', care nu este același lucru cu 'connection reset', este cauzat de probleme de rețea care trimit de la capătul dumneavoastră. Există un articol din baza de cunoștințe Microsoft despre acest lucru.

Comentarii (1)

Resetarea conexiunii înseamnă pur și simplu că a fost primit un TCP RST. Acest lucru se întâmplă atunci când omologul dvs. primește date pe care nu le poate procesa, iar motivele pot fi diverse.

Cel mai simplu este atunci când închideți socket-ul și apoi scrieți mai multe date pe fluxul de ieșire. Prin închiderea socket-ului, i-ați spus omologului dvs. că ați terminat de vorbit și că poate uita de conexiunea dvs. Atunci când trimiteți oricum mai multe date pe acel flux, omologul le respinge cu un RST pentru a vă anunța că nu vă ascultă.

În alte cazuri, un firewall care intervine sau chiar gazda la distanță însăși ar putea "uita" de conexiunea dumneavoastră TCP. Acest lucru s-ar putea întâmpla dacă nu trimiteți date pentru o perioadă lungă de timp (2 ore este un termen de expirare obișnuit) sau pentru că omologul a fost repornit și și-a pierdut informațiile despre conexiunile active. Trimiterea de date pe una dintre aceste conexiuni defuncte va provoca și ea un RST.


Actualizare ca răspuns la informații suplimentare:

Uitați-vă cu atenție la modul în care gestionați SocketTimeoutException. Această excepție este ridicată dacă este depășit timpul de așteptare configurat în timp ce este blocată o operațiune pe socket. Starea socket-ului în sine nu se modifică atunci când această excepție este lansată, dar dacă gestionarul de excepții închide socket-ul și apoi încearcă să scrie pe el, veți fi într-o stare de resetare a conexiunii. setSoTimeout() este menit să vă ofere o modalitate curată de a ieși dintr-o operațiune read() care altfel s-ar putea bloca la nesfârșit, fără a face lucruri murdare, cum ar fi închiderea socket-ului de pe un alt fir.

Comentarii (2)

Ori de câte ori am avut probleme ciudate de acest gen, de obicei mă așez cu un instrument precum WireShark și mă uit la datele brute care sunt transmise de la un capăt la altul. S-ar putea să fiți surprins unde lucrurile sunt deconectate, iar dumneavoastră sunteți notificat doar atunci când încercați să citiți.

Comentarii (0)