Angesichts dieses Stack-Trace-Snippets
Auslöser: java.net.SocketException: Software verursachte Verbindungsabbruch: Socket-Schreibfehler
bei java.net.SocketOutputStream.socketWrite0 (native Methode)
Ich habe versucht, folgende Fragen zu beantworten:
- Welcher Code löst diese Ausnahme aus? (JVM? / Tomcat? / Mein Code?)
- Was bewirkt, dass diese Ausnahme ausgelöst wird?
Zu # 1:
Die JVM-Quelle von Sun enthält nicht genau diese Nachricht, aber ich denke, der Text, den die Software verursacht hat, hat den Verbindungsabbruch verursacht: Der Socket-Schreibfehler stammt von der nativen Implementierung von SocketOutputStream
:
private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
int len) throws IOException;
In Bezug auf # 2
Ich vermute, dass dies verursacht wird, wenn der Client die Verbindung beendet hat, bevor die vollständige Antwort erhalten wurde (z. B. eine Anfrage gesendet, aber bevor die vollständige Antwort erhalten wurde, wurde sie geschlossen / beendet / offline).
Fragen:
- Sind die obigen Annahmen korrekt (Nr. 1 und Nr. 2)?
- Kann dies von der Situation unterschieden werden: "konnte aufgrund eines Netzwerkfehlers auf der Serverseite nicht auf den Client schreiben "? oder würde das die gleiche Fehlermeldung darstellen?
- Und das Wichtigste: Gibt es ein offizielles Dokument (z. B. von Sun), in dem dies angegeben ist?
Ich brauche einen Beweis dafür, dass diese Stapelverfolgung der "Fehler" des Socket-Clients ist, und es gibt nichts, was der Server hätte tun können, um dies zu vermeiden. (außer das Abfangen der Ausnahme oder die Verwendung eines SocketOutputStream, der nicht von Sun JVM stammt, obwohl beide die Tatsache, dass der Client beendet wurde, nicht wirklich vermeiden)
outs.write(audioBytes);
)byte[]
inOutputStream
. Wenn Audio läuft und während der Wiedergabe, wenn der Benutzer auf ein anderes Menü klickt (das eine Serveranforderung sendet), wird auf der Konsole der gleiche Fehler angezeigt. Ist es also sicher, diese Ausnahme zu ignorieren?Antworten:
Siehe diesen MSDN-Artikel . Siehe auch Einige Informationen zu "Software verursachte Verbindungsabbruch" .
quelle
Das
java.net.SocketException
wird ausgelöst, wenn beim Erstellen oder Zugreifen auf einen Socket (z. B. TCP ) ein Fehler auftritt . Dies kann normalerweise verursacht werden, wenn der Server die Verbindung beendet hat (ohne sie ordnungsgemäß zu schließen), bevor die vollständige Antwort angezeigt wird. In den meisten Fällen kann dies entweder durch das Timeout-Problem verursacht werden (z. B. die Antwort dauert zu lange oder der Server ist mit den Anforderungen überlastet), oder der Client hat die SYN gesendet, aber keine ACK empfangen (Bestätigung der Verbindungsbeendigung). . Bei Timeout-Problemen können Sie den Timeout-Wert erhöhen.Die Socket-Ausnahme enthält normalerweise die angegebene Detailmeldung zu dem Problem.
Beispiel für detaillierte Nachrichten:
Der Fehler weist auf einen Versuch hin, die Nachricht zu senden, und die Verbindung wurde von Ihrem Server abgebrochen. Wenn dies beim Herstellen einer Verbindung zur Datenbank passiert ist, kann dies mit der Verwendung eines nicht kompatiblen Connector / J-JDBC-Treibers zusammenhängen .
Mögliche Lösung: Stellen Sie sicher, dass Ihr CLASSPATH über die richtigen Bibliotheken / Treiber verfügt.
Dies kann passieren, wenn beim Herstellen einer Verbindung zur Fernbedienung ein Problem auftritt. Zum Beispiel, weil der Virenprüfer die Remote-Mail-Anforderungen ablehnt .
Mögliche Lösung: Überprüfen Sie den Virenscan-Dienst, ob er den Port für ausgehende Verbindungsanforderungen blockiert.
Mögliche Lösung: Stellen Sie sicher, dass Sie die richtige Länge von Bytes in den Stream schreiben. Überprüfen Sie also genau, was Sie senden. Siehe diesen Thread .
Die Anwendung hat nicht überprüft, ob auf der Serverseite eine Zeitüberschreitung für die Keep-Alive-Verbindung aufgetreten ist.
Mögliche Lösung: Stellen Sie sicher, dass der HttpClient nicht null ist, bevor Sie aus der Verbindung lesen. E13222_01
Die Verbindung wurde vom Peer (Server) beendet.
Die Verbindung wurde entweder vom Client beendet oder vom Serverende der Verbindung aufgrund einer Anforderung mit der Anforderung geschlossen.
Siehe: Was verursacht meine java.net.SocketException: Verbindung zurückgesetzt?
quelle
HttpClient
Wesennull
kann unmöglich a verursachenSocketException
. Nicht die richtige Länge in den Stream zu schreiben, tut dies auch nicht.Ich habe dies am häufigsten gesehen, wenn eine Unternehmensfirewall auf einer Workstation / einem Laptop im Weg steht und die Verbindung unterbrochen wird.
z.B. Ich habe einen Serverprozess und einen Clientprozess auf demselben Computer. Der Server überwacht alle Schnittstellen (0.0.0.0) und der Client versucht, eine Verbindung zur öffentlichen / privaten Schnittstelle herzustellen (beachten Sie nicht die Loopback-Schnittstelle 127.0.0.1).
Wenn das Netzwerk der Maschine getrennt ist (z. B. WLAN ausgeschaltet), wird die Verbindung hergestellt. Wenn der Computer mit dem Unternehmensnetzwerk verbunden ist (direkt oder VPN), wird die Verbindung hergestellt.
Wenn der Computer jedoch mit einem öffentlichen WLAN (oder Heimnetzwerk) verbunden ist, wird die Verbindung durch die Firewall unterbrochen. In dieser Situation funktioniert das Verbinden des Clients mit der Loopback-Schnittstelle einwandfrei, nur nicht mit der Home / Public-Schnittstelle.
Hoffe das hilft.
quelle
Um zu beweisen, welche Komponente ausfällt, würde ich die TCP / IP-Kommunikation mithilfe von Wireshark überwachen und prüfen , wer den Port tatsächlich schließt. Auch Zeitüberschreitungen könnten relevant sein.
quelle
Haben Sie den Tomcat-Quellcode und die JVM-Quelle überprüft ? Das kann Ihnen mehr Hilfe geben.
Ich denke, Ihr allgemeines Denken ist gut. Ich würde
ConnectException
in dem Szenario ein erwarten , dass Sie keine Verbindung herstellen konnten. Das Obige sieht sehr nach Client aus.quelle
Für alle, die einfache Client Server-Programme verwenden und diesen Fehler erhalten, handelt es sich um ein Problem nicht geschlossener (oder zu früh geschlossener) Eingabe- oder Ausgabestreams.
quelle
Ich stand vor dem gleichen Problem.
Häufig tritt diese Art von Fehler auf, weil der Client seine Verbindung geschlossen hat und der Server immer noch versucht, auf diesen Client zu schreiben.
Stellen Sie also sicher, dass die Verbindung Ihres Clients geöffnet ist, bis der Server mit seinem Ausgabestream fertig ist.
Und noch etwas: Vergessen Sie nicht, den Eingabe- und Ausgabestream zu schließen.
Hoffe das hilft.
Und wenn Sie immer noch vor einem Problem stehen, informieren Sie Ihr Problem hier ausführlich.
quelle
Dieser Fehler ist mir beim Testen meines Seifendienstes mit dem SoapUI-Client passiert. Im Grunde habe ich versucht, eine sehr große Nachricht (> 500 KB) zu erhalten, und SoapUI hat die Verbindung durch Timeout geschlossen.
... und geben Sie einen großen Wert ein, z. B. 180000 (3 Minuten). Dies ist keine perfekte Lösung für Ihr Problem, da die Datei tatsächlich zu groß ist, aber zumindest eine Antwort erhalten.
quelle
Geschlossene Verbindung in einem anderen Client
In meinem Fall war der Fehler:
Es wurde in Eclipse beim Debuggen einer Java-Anwendung empfangen, die auf eine H2-Datenbank zugreift. Die Fehlerquelle war, dass ich die Datenbank zunächst mit SQuirreL geöffnet hatte, um die Integrität manuell zu überprüfen. Ich habe das Flag verwendet, um mehrere Verbindungen zu derselben Datenbank zu aktivieren (dh
AUTO_SERVER=TRUE
) , sodass es keine Probleme gab, über Java eine Verbindung zur Datenbank herzustellen.Der Fehler trat auf, als ich nach einer Weile - es ist ein langer Java-Prozess - beschloss, SQuirreL zu schließen, um Ressourcen freizugeben. Es scheint, als ob SQuirreL die DB-Serverinstanz "besitzt" und mit der SQuirreL-Verbindung heruntergefahren wurde.
Beim Neustart der Java-Anwendung wurde der Fehler nicht erneut angezeigt.
config
quelle
In meinem Fall habe ich die Client- und die Serverseite entwickelt, und ich habe die Ausnahme:
wenn Klassen in Client und Server unterschiedlich sind. Ich lade keine Serverklassen (Schnittstellen) auf den Client herunter, sondern füge dem Projekt dieselben Dateien hinzu. Aber der Weg muss genau der gleiche sein. Zum Beispiel habe ich auf dem Serverprojekt Java \ rmi \ services-Pakete mit einigen serviceInterface und Implementierungen. Ich muss dasselbe Paket auf dem Client-Projekt erstellen. Wenn ich es zum Beispiel durch java / rmi / server / services ändere, erhalte ich die obige Ausnahme. Dieselbe Ausnahme, wenn die Schnittstellenversion zwischen Client und Server unterschiedlich ist (auch wenn versehentlich eine leere Zeile hinzugefügt wurde ... Ich denke, rmi erstellt eine Art Hash von Klassen, um die Version zu überprüfen ... Ich weiß nicht ... Wenn es möglich wäre Hilfe ...
quelle
Mein Server hat diese Ausnahme im Pass 2 Tage ausgelöst und ich habe sie gelöst, indem ich die Trennfunktion verschoben habe mit:
Bis zum Ende des Listing-Threads. wenn es jemandem hilft.
quelle
In der unten erläuterten Situation wird die Clientseite eine solche Ausnahme auslösen:
Der Server wird aufgefordert, das Clientzertifikat zu authentifizieren. Der Client stellt jedoch ein Zertifikat bereit, dessen erweiterte Schlüsselverwendung die Clientauthentifizierung nicht unterstützt. Daher akzeptiert der Server das Clientzertifikat nicht und schließt dann die Verbindung.
quelle
SSL-Client-Seite wird eine solche Ausnahme in der folgenden Situation auslösen (ich hatte getestet) ,:
Der Server wird aufgefordert, das Clientzertifikat zu authentifizieren. Der Client stellt jedoch ein Zertifikat bereit, das die erweiterte Schlüsselverwendung nicht für die Clientauthentifizierung unterstützt.
quelle
Ich hatte das gleiche Problem mit wireMock, als ich die restlichen API-Aufrufe verspottete. Früher habe ich den Server folgendermaßen definiert:
Es sollte jedoch wie folgt definiert werden:
quelle
NullPointerException
, nicht dieses Problem verursachen.