java.net.SocketException: Verbinding gereset

Ik krijg de volgende foutmelding als ik probeer te lezen van een socket. Ik doe een readInt() op die InputStream, en ik krijg deze foutmelding. Als ik de documentatie erop nasla, suggereert dit dat het client gedeelte van de verbinding de verbinding heeft gesloten. In dit scenario, ben ik de server.

Ik heb toegang tot de logbestanden van de client en deze sluit de verbinding niet, en in feite suggereren de logbestanden dat ik de verbinding sluit. Dus heeft iemand een idee waarom dit gebeurt? Waar moet ik nog meer op controleren? Doet dit zich voor als er lokale bronnen zijn die misschien drempels bereiken?


Ik merk wel op dat ik de volgende regel heb:

socket.setSoTimeout(10000);

vlak voor de readInt(). Hier is een reden voor (lang verhaal), maar gewoon nieuwsgierig, zijn er omstandigheden waaronder dit tot de aangegeven fout zou kunnen leiden? Ik heb de server in mijn IDE draaien, en ik liet mijn IDE toevallig vastlopen op een breakpoint, en toen zag ik dat precies dezelfde fouten begonnen te verschijnen in mijn eigen logs in mijn IDE.

Hoe dan ook, ik zeg het maar even, hopelijk is het geen afleidingsmanoeuvre. :-(

Er zijn verschillende mogelijke oorzaken.

  1. Het andere eind heeft opzettelijk de verbinding gereset, op een manier die ik hier niet zal documenteren. Het is zeldzaam, en over het algemeen onjuist, voor toepassingssoftware om dit te doen, maar het is niet onbekend voor commerciële software.

  2. Het wordt vaker veroorzaakt door het schrijven naar een verbinding die aan de andere kant al normaal gesloten is. Met andere woorden een fout in het applicatieprotocol.

  3. Het kan ook worden veroorzaakt door het sluiten van een socket wanneer er ongelezen gegevens in de ontvangstbuffer van de socket zitten.

  4. In Windows, 'software caused connection abort', wat niet hetzelfde is als 'connection reset', wordt veroorzaakt door netwerkproblemen bij het verzenden vanaf uw kant. Er'is een Microsoft knowledge base artikel over dit.

Commentaren (1)

Verbindingsreset betekent eenvoudigweg dat een TCP RST ontvangen werd. Dit gebeurt wanneer uw peer gegevens ontvangt die hij niet kan verwerken, en daar kunnen verschillende redenen voor zijn.

De eenvoudigste is wanneer je de socket sluit, en dan meer gegevens schrijft op de uitvoerstroom. Door de socket te sluiten, vertel je je peer dat je klaar bent met praten, en dat hij je verbinding kan vergeten. Wanneer je toch meer gegevens naar die stroom stuurt, weigert de peer dat met een RST om je te laten weten dat hij niet luistert.

In andere gevallen kan een tussenliggende firewall of zelfs de remote host zelf "vergeet" over uw TCP-verbinding. Dit kan gebeuren als u lange tijd geen gegevens verstuurt (2 uur is een gebruikelijke time-out), of omdat de peer opnieuw werd opgestart en zijn informatie over actieve verbindingen verloor. Gegevens verzenden op één van deze in onbruik geraakte verbindingen zal ook een RST veroorzaken.


Update in antwoord op aanvullende informatie:

Kijk eens goed naar je afhandeling van de SocketTimeoutException. Deze exception wordt opgewekt als de geconfigureerde timeout wordt overschreden tijdens een geblokkeerde socket operatie. De status van de socket zelf wordt niet veranderd wanneer deze exceptie wordt gegooid, maar als je exception handler de socket sluit, en er dan naar probeert te schrijven, kom je in een connection reset conditie. setSoTimeout() is bedoeld om je een schone manier te geven om uit een read() operatie te breken die anders voor altijd zou kunnen blokkeren, zonder vieze dingen te doen zoals het sluiten van de socket vanuit een andere thread.

Commentaren (2)

Wanneer ik dit soort vreemde problemen heb gehad, ga ik meestal zitten met een tool als WireShark en kijk naar de ruwe data die heen en weer wordt gestuurd. Het zou u kunnen verbazen waar de verbinding verbroken wordt, en u alleen een melding krijgt wanneer u probeert te lezen.

Commentaren (0)