2008-09-15 10 views
80

Ich erhalte den folgenden Fehler versuchen, von einem Socket zu lesen. Ich mache eine readInt() auf diesem InputStream, und ich bekomme diesen Fehler. Wenn Sie die Dokumentation durchlesen, deutet dies darauf hin, dass der Client-Teil der Verbindung die Verbindung geschlossen hat. In diesem Szenario bin ich der Server.java.net.SocketException: Verbindung zurückgesetzt

Ich habe Zugriff auf die Client-Protokolldateien und es schließt nicht die Verbindung, und in der Tat schlagen seine Protokolldateien vor, dass ich die Verbindung schließe. Hat also jemand eine Idee, warum das passiert? Worauf sollte man sonst noch achten? Tritt dies auf, wenn lokale Ressourcen Schwellenwerte erreichen?


ich anmerken, dass ich die folgende Zeile haben:

socket.setSoTimeout(10000); 

kurz vor dem readInt(). Es gibt einen Grund dafür (lange Geschichte), aber nur neugierig, gibt es Umstände, unter denen dies zum angegebenen Fehler führen könnte? Ich habe den Server in meiner IDE ausgeführt, und ich habe zufällig meine IDE an einem Haltepunkt stecken, und ich bemerkte dann, dass genau die gleichen Fehler in meinen eigenen Protokollen in meiner IDE erscheinen.

Wie auch immer, nur erwähnen, hoffentlich nicht ein Hering. :-(

+0

Haben Sie Spuren von beiden Seiten haben stapeln? Können Sie die Netzwerkarchitektur etwas genauer beschreiben? (Über dem wilden Internet? Auf der gleichen Maschine? Irgendwo dazwischen?) Passiert es die ganze Zeit? Oder zeitweise? –

Antwort

8

Immer wenn ich solche Probleme hatte, setze ich mich normalerweise mit einem Werkzeug wie WireShark hin und schaue mir die Rohdaten an, die hin und her gereicht werden.Man könnte überrascht sein, wo Dinge unterbrochen werden, und das bist du nur informiert zu werden, wenn Sie versuchen und lesen.

31

Anschluss zurück bedeutet einfach, dass eine TCP-RST empfangen wurde. Dies geschieht, wenn Ihre Peer-Daten empfängt, die es nicht verarbeiten kann, und es kann verschiedene Gründe geben.

Am einfachsten ist es, wenn Sie den Socket schließen und dann mehr Daten in den Ausgabestream schreiben, indem Sie den Socket schließen bedenke, dass du fertig bist und du deine Verbindung vergessen kannst. Wenn Sie trotzdem mehr Daten für diesen Stream senden, weist der Peer diesen mit einer RST zurück, damit Sie wissen, dass er nicht abhört.

In anderen Fällen kann eine intervenierende Firewall oder sogar der Remote-Host selbst Ihre TCP-Verbindung "vergessen". Dies kann passieren, wenn Sie lange Zeit keine Daten senden (2 Stunden ist eine gemeinsame Zeitüberschreitung), oder weil der Peer neu gestartet wurde und seine Informationen über aktive Verbindungen verloren hat. Das Senden von Daten über eine dieser nicht funktionierenden Verbindungen führt ebenfalls zu einer RST.


-Update in Reaktion auf weitere Informationen:

Werfen Sie einen Blick auf Ihre Handhabung des SocketTimeoutException. Diese Ausnahme wird ausgelöst, wenn das konfigurierte Zeitlimit überschritten wird, während es bei einer Socket-Operation blockiert wird. Der Status des Sockets selbst wird nicht geändert, wenn diese Ausnahme ausgelöst wird. Wenn jedoch Ihr Ausnahmehandler den Socket schließt und dann versucht, in den Socket zu schreiben, befinden Sie sich in einer Verbindungszurücksetzungsbedingung. setSoTimeout() soll Ihnen einen sauberen Weg geben, um aus einer read() Operation auszubrechen, die sonst für immer blockieren könnte, ohne schmutzige Dinge wie das Schließen des Sockets von einem anderen Thread zu tun.

+0

In mehrfacher Hinsicht nicht korrekt. Garbage Collection- und Process-Exits führen beide zum Schließen, nicht zum Zurücksetzen, aber ein Schließen, gefolgt von einem Schreiben durch den Peer, kann einen Reset und nicht ein EOS auslösen. SocketTimeoutExceptions werden nur ausgelöst, wenn der Reader ein Lese-Timeout festgelegt hat. – EJP

+0

Und es bedeutet nicht immer, dass eine RST empfangen wurde. Es kann auch bedeuten, dass man von dieser Seite generiert wurde. – EJP

+3

EJP noch 5 Jahre später salzig? – Daedric

81

Es gibt mehrere mögliche Ursachen.

  1. Das andere Ende zurückgesetzt hat bewusst die Verbindung, in einer Weise, die ich hier nicht dokumentieren. Es ist selten und im Allgemeinen falsch, dass Anwendungssoftware dies tut, aber es ist für kommerzielle Software nicht unbekannt.

  2. Häufiger wird es durch Schreiben in eine Verbindung verursacht, dass das andere Ende bereits normal geschlossen ist. Mit anderen Worten ein Anwendungsprotokollfehler.

  3. Es kann auch durch Schließen eines Sockets verursacht werden, wenn ungelesene Daten im Socket-Empfangspuffer vorhanden sind.

  4. In Windows wird "Software verursachte Verbindungsabbruch", die nicht das gleiche wie "Verbindungszurücksetzung" ist, durch Netzwerkprobleme verursacht, die von Ihrem Ende senden. Dazu gibt es einen Microsoft Knowledge Base-Artikel.

+1

FYI http://support.microsoft.com/kb/204594 –

+0

@MattLyons Danke. Es gibt viel bessere MSDN-Artikel als das. Ehrlich gesagt finde ich das schwer zu glauben. Eine Verbindung besteht nicht einmal, bis die korrekten Quell- und Ziel-IP-Adressen eingerichtet wurden. Die MSDN-Artikel, die ich gesehen habe, beziehen sich auf permanente Netzwerkfehler, die die Verbindung verzögern. – EJP

3

Ich hatte den gleichen Fehler. Ich habe jetzt die Lösung für das Problem gefunden. Das Problem war, dass das Client-Programm fertig war, bevor der Server die Streams las.

+0

Das würde diese Ausnahme nicht alleine verursachen. – EJP

+0

wäre es, wenn System.exit (0) das Programm beendet und niemand socket.close() aufruft, da die Verbindung in einem schlechten Zustand ist und nicht richtig geschlossen wurde. sooo richtiger gesagt, er hatte ein Client-Programm, das ohne Schließen von Sockets herunterfahren;) Das ist eine schlechte Sache und sollte behoben werden. –

+0

@DeanHiller Nein, würde es nicht. Das Betriebssystem würde den Socket auf die gleiche Weise wie die Anwendung schließen. – EJP

5

Peinlich, es zu sagen, aber als ich dieses Problem hatte, war es einfach ein Fehler, dass ich die Verbindung schloss, bevor ich alle Daten las. In Fällen, in denen kleine Strings zurückgegeben wurden, funktionierte es, aber das lag vermutlich daran, dass die gesamte Antwort gepuffert war, bevor ich sie schloss.

In Fällen, in denen längere Textmengen zurückgegeben werden, wurde die Ausnahme ausgelöst, da mehr als ein Puffer zurückgegeben wurde.

Sie könnten nach diesem Überblick suchen. Denken Sie daran, eine URL wie eine Datei zu öffnen, stellen Sie sicher, dass Sie sie schließen (die Verbindung freigeben), sobald sie vollständig gelesen wurde.

1

Ich hatte auch dieses Problem mit einem Java-Programm, das versucht, einen Befehl auf einem Server über SSH zu senden. Das Problem bestand darin, dass der Computer den Java-Code ausführte. Es war nicht berechtigt, eine Verbindung zum Remote-Server herzustellen. Die write() -Methode war in Ordnung, aber die read() -Methode warf ein java.net.SocketException: Connection reset. Ich habe dieses Problem mit dem Hinzufügen des Client-SSH-Schlüssels zu den bekannten Schlüsseln des Remoteservers behoben.

2

Ich hatte dieses Problem mit einem SOA-System in Java geschrieben. Ich habe sowohl den Client als auch den Server auf verschiedenen physischen Rechnern ausgeführt und sie funktionierten lange Zeit einwandfrei. Dann erschienen diese widerlichen Verbindungs-Resets im Client-Protokoll und es gab nichts Ungewöhnliches im Serverprotokoll. Das Neustarten von Client und Server hat das Problem nicht behoben. Schließlich stellten wir fest, dass der Heap auf der Serverseite ziemlich voll war, so dass wir den für die JVM verfügbaren Speicher erhöhten: Problem gelöst! Beachten Sie, dass es kein OutOfMemoryError im Protokoll gab: Speicher war knapp, nicht erschöpft.

5

Sie sollten sehr sorgfältig vollständige Spur inspizieren,

Ich habe eine Server-Socket-Anwendung und fixierte einen java.net.SocketException: Connection reset Fall.

In meinem Fall passiert es beim Lesen von einem ClientSocket Socket Objekt, das seine Verbindung aus irgendeinem Grund geschlossen ist. (Netzwerk verloren, Firewall oder Anwendung stürzt ab oder soll geschlossen werden)

Eigentlich habe ich die Verbindung wieder hergestellt, als ich einen Fehler beim Lesen von diesem Socket-Objekt bekommen habe.

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

Das Interessante ist, for my JAVA Socket wenn ein Kunde zu meinem ServerSocket verbindet und die Verbindung schließen, ohne etwas zu senden is.read() selbst nennt recursively.It zum Lesen dieser Buchse wegen des Seins in einem unendlichen while-Schleife scheint, dass Sie versuchen, zu lesen von einer geschlossenen Verbindung. Wenn Sie etwas wie unten für den Lesevorgang verwenden;

while(true) 
{ 
    Receive(); 
} 

Dann erhalten Sie einen stacktrace etwas wie unten und auf

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

Was ich tat nur ServerSocket- Schließen und meine Verbindung zu erneuern und für alle weiteren eingehenden Client-Verbindungen warten

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


//... 
} 

Dies stellt meine Verbindung für unbekannte Client-Socket-Verlusten wieder her

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

Ich konnte keinen anderen Weg finden, weil Sie von unten Bild sehen können Sie nicht verstehen, ob Verbindung verloren ist oder nicht ohne eine try and catch, weil alles scheint richtig. Ich habe diesen Schnappschuss bekommen, während ich kontinuierlich Connection reset bekam.

enter image description here

Verwandte Themen