Ich verwende den http-Client von Apache Commons, um die URL mithilfe der Post-Methode aufzurufen, um die Parameter zu veröffentlichen, und es wird selten der folgende Fehler ausgegeben.
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at org.apache.commons.httpclient.methods.ByteArrayRequestEntity.writeRequest(ByteArrayRequestEntity.java:90)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
Kann jemand vorschlagen, was diese Ausnahme verursacht und wie man sie debuggt?
Antworten:
Dies wird verursacht durch:
In beiden Fällen haben Sie also ein schlecht definiertes oder implementiertes Anwendungsprotokoll.
Es gibt einen dritten Grund, den ich hier nicht dokumentieren werde, bei dem der Peer jedoch absichtlich Maßnahmen ergreift, um die Verbindung zurückzusetzen, anstatt sie ordnungsgemäß zu schließen.
quelle
XMLHttpRequest.abort()
) gesehen.In unserem Fall haben wir dies bei einem Auslastungstest auf unserem App-Server festgestellt. Es stellte sich heraus, dass wir unserer JVM zusätzlichen Speicher hinzufügen müssen, da sie knapp wird. Dies löste das Problem.
Versuchen Sie, den für die JVM verfügbaren Speicher zu erhöhen, oder überwachen Sie die Speichernutzung, wenn diese Fehler auftreten.
quelle
SocketException: Eine unterbrochene Pipe wird dadurch verursacht, dass das 'andere Ende' (der Client oder der Server) die Verbindung schließt, während Ihr Code entweder von der Verbindung liest oder in diese schreibt.
Dies ist eine sehr häufige Ausnahme in Client / Server-Anwendungen, die Datenverkehr von Clients oder Servern außerhalb der Anwendungssteuerung empfangen. Der Client ist beispielsweise ein Browser. Wenn der Browser einen Ajax-Anruf tätigt und / oder der Benutzer die Seite oder den Browser einfach schließt, kann dies die gesamte Kommunikation unerwartet beenden. Grundsätzlich wird dieser Fehler jedes Mal angezeigt, wenn das andere Ende seine Anwendung beendet, und Sie haben ihn nicht erwartet.
Wenn diese Ausnahme in Ihrer Anwendung auftritt, sollten Sie Ihren Code überprüfen, in dem die E / A (Eingabe / Ausgabe) auftritt, und ihn mit einem Try / Catch-Block umschließen, um diese E / A-Ausnahme abzufangen. Es liegt dann an Ihnen, zu entscheiden, wie Sie mit dieser halbgültigen Situation umgehen möchten.
In Ihrem Fall ist der Anruf an
HttpMethodDirector.executeWithRetry
- der früheste Ort, an dem Sie noch die Kontrolle haben - Stellen Sie also sicher, dass der Anruf mit dem Try / Catch-Block abgeschlossen ist, und behandeln Sie ihn so, wie Sie es für richtig halten.Ich würde dringend davon abraten, SocketException-Broken Pipe-spezifische Fehler auf anderen als Debug- / Trace-Ebenen zu protokollieren. Andernfalls kann dies als eine Form von DOS-Angriff (Denial Of Service) verwendet werden, indem die Protokolle ausgefüllt werden. Versuchen Sie, Ihre Anwendung für dieses häufige Szenario zu härten und negativ zu testen.
quelle
Alle offenen Streams und Verbindungen müssen ordnungsgemäß geschlossen sein. Wenn wir das nächste Mal versuchen, das urlConnection-Objekt zu verwenden, wird kein Fehler ausgegeben. Als Beispiel hat die folgende Codeänderung den Fehler für mich behoben.
Vor:
Nach dem:
quelle
BufferedOutputStream
immerclose()
den zugrunde liegenden Ausgabestream (also den Ausgabestream vonurlConnection
) aufruft . Siehe docs.oracle.com/javase/6/docs/api/java/io/… und docs.oracle.com/javase/6/docs/api/java/io/…. Wenn Sie also anrufenos.close()
, sollte es bereits geschlossen sein . Nein?Ich habe die Funktion zum Herunterladen von Daten über den FTP-Server implementiert und dort auch die gleiche Ausnahme festgestellt, als ich den Download fortgesetzt habe. Um diese Ausnahme zu beheben, müssen Sie immer die Verbindung zur vorherigen Sitzung trennen und eine neue Instanz des Clients sowie eine neue Verbindung zum Server erstellen. Dieser Ansatz könnte auch für HTTPClient hilfreich sein.
quelle
Ich hatte das gleiche Problem, als ich eine einfache Java-Anwendung entwickelte, die einen bestimmten TCP abhört. Normalerweise hatte ich kein Problem, aber als ich einen Stresstest durchführte, bemerkte ich, dass eine Verbindung mit einem Fehler unterbrochen wurde
socket write exception
.Nach der Untersuchung habe ich eine Lösung gefunden, die mein Problem löst. Ich weiß, dass diese Frage ziemlich alt ist, aber ich teile meine Lösung lieber mit, jemand kann sie nützlich finden.
Das Problem war bei der ServerSocket-Erstellung. Ich habe aus Javadoc gelesen, dass es ein Standardlimit von 50 ausstehenden Sockets gibt. Wenn Sie versuchen, eine andere Verbindung herzustellen, werden diese abgelehnt. Die Lösung besteht einfach darin, diese Standardkonfiguration auf der Serverseite zu ändern. Im folgenden Fall erstelle ich einen Socket-Server, der den TCP-Port überwacht
10_000
und maximal200
ausstehende Sockets akzeptiert .Aus Javadoc von ServerSocket :
quelle
Das Problem könnte sein, dass Ihre bereitgestellten Dateien nicht mit den richtigen RMI-Methoden aktualisiert werden. Überprüfen Sie, ob Ihre RMI-Schnittstelle über aktualisierte Parameter oder aktualisierte Datenstrukturen verfügt, über die Ihr Client nicht verfügt. Oder dass Ihr RMI-Client keine Parameter hat, die sich von denen Ihrer Serverversion unterscheiden.
Dies ist nur eine fundierte Vermutung. Nach dem erneuten Bereitstellen der Klassendateien meiner Serveranwendung und dem erneuten Testen ist das Problem "Broken Pipe" behoben.
quelle
Die obigen Antworten veranschaulichen den Grund dafür
java.net.SocketException: Broken pipe
: Das andere Ende hat die Verbindung geschlossen. Ich möchte Erfahrungen austauschen, die passiert sind, als ich darauf gestoßen bin:Content-Type
Header fälschlicherweise größer gesetzt als der Anfragetext tatsächlich ist (tatsächlich gab es überhaupt keinen Text).Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.net.SocketTimeoutException: null
java.net.SocketException: Broken pipe
weil der Client es geschlossen hat.Manchmal löst Tomcat keine defekte Pip-Ausnahme aus, da eine Timeout-Ausnahme die Verbindung schließt, weshalb mich ein solcher Unterschied auch verwirrt.
quelle
Content-Type
Header gibt keine Zahl an, daher kann er nicht größer als alles andere sein. Timeout-Ausnahmen schließen den Socket nicht. Antwort macht überhaupt keinen Sinn.Sie sollten beispielsweise den Parameter "backlog" Ihres ServerSocket erhöhen
quelle
Die Ursache ist, dass der Remote-Peer seinen Socket schließt (z. B. Absturz). Wenn Sie also beispielsweise versuchen, Daten in ihn zu schreiben, erhalten Sie dies. Um dies zu lösen, schützen Sie Lese- / Schreibvorgänge für Socket-Vorgänge zwischen (try catch) und verwalten Sie dann den Fall des Verbindungsverlusts im catch (Verbindung erneuern, Programm stoppen usw.):
quelle