Jeg får følgende fejl ved at forsøge at læse fra en socket. Jeg laver en readInt()
på denne InputStream
, og jeg får denne fejl. Ved at gennemse dokumentationen tyder det på, at klientdelen af forbindelsen lukkede forbindelsen. I dette scenario er jeg serveren.
Jeg har adgang til klientens logfiler, og den lukker ikke forbindelsen, og dens logfiler antyder faktisk, at jeg lukker forbindelsen. Er der nogen, der har en idé om, hvorfor dette sker? Hvad skal man ellers tjekke for? Opstår dette, når der er lokale ressourcer, der måske når tærskelværdier?
Jeg bemærker dog, at jeg har følgende linje:
socket.setSoTimeout(10000);
lige før readInt()
. Der er en grund til dette (lang historie), men bare nysgerrig, er der omstændigheder under hvilke dette kan føre til den angivne fejl? Jeg har serveren kørende i mit IDE, og jeg lod tilfældigvis mit IDE sidde fast på et breakpoint, og jeg bemærkede derefter, at nøjagtig de samme fejl begyndte at dukke op i mine egne logs i mit IDE.
Anyway, nævner det bare, forhåbentlig ikke en rød tråd. :-(
Der er flere mulige årsager.
Den anden ende har med vilje nulstillet forbindelsen på en måde, som jeg ikke vil dokumentere her. Det er sjældent, og generelt forkert, at applikationssoftware gør dette, men det er ikke ukendt for kommerciel software.
Det er mere almindeligt, at det skyldes, at der skrives til en forbindelse, som den anden ende allerede har lukket normalt. Med andre ord en programprotokolfejl.
Det kan også forårsages af at lukke en socket, når der er ulæste data i socketmodtagerbufferen.
I Windows er 'software forårsaget forbindelsesafbrydelse';, som ikke er det samme som 'forbindelsesreset', forårsaget af netværksproblemer, der sendes fra din ende. Der findes en Microsoft Knowledge Base-artikel om dette.
Reset af forbindelsen betyder blot, at der er modtaget en TCP RST. Dette sker, når din peer modtager data, som den ikke kan behandle, og det kan der være forskellige årsager til.
Den enkleste er, når du lukker socket'en og derefter skriver flere data på outputstrømmen. Ved at lukke socket'en fortæller du din peer, at du er færdig med at tale, og at den kan glemme forbindelsen. Når du alligevel sender flere data på den stream, afviser peer'en dem med en RST for at fortælle dig, at den ikke lytter.
I andre tilfælde kan en mellemliggende firewall eller endog fjernværten selv glemme din TCP-forbindelse. Det kan ske, hvis du ikke sender data i lang tid (2 timer er en almindelig timeout), eller fordi peer-adressen er blevet genstartet og har mistet sine oplysninger om aktive forbindelser. Hvis du sender data på en af disse nedbrudte forbindelser, vil det også forårsage en RST.
opdatering som svar på yderligere oplysninger:
Se nøje på din håndtering af SocketTimeoutException
. Denne undtagelse opstår, hvis den konfigurerede timeout overskrides, mens den er blokeret i en socket-operation. Selve socketens tilstand ændres ikke, når denne undtagelse udløses, men hvis din undtagelsesbehandler lukker socket'en og derefter forsøger at skrive til den, vil du komme i en tilstand, hvor forbindelsen nulstilles. setSoTimeout()
er beregnet til at give dig en ren måde at bryde ud af en read()
-operation, der ellers kan blokere for evigt, uden at gøre beskidte ting som at lukke socket fra en anden tråd.
Når jeg har haft mærkelige problemer som dette, sætter jeg mig normalt ned med et værktøj som WireShark og ser på de rå data, der sendes frem og tilbage. Du kan blive overrasket over, hvor tingene bliver afbrudt, og du bliver kun anmeldt, når du forsøger at læse.