Bei der Verbindung mit einem Server mit einem Java-Client-Socket hatte ich zwei verschiedene Timeout-Ausnahmen.
%Vor% Ich habe die Dokumentation überprüft, aber für SocketTimeoutException
steht geschrieben: "Signalisiert, dass ein Timeout beim Lesen oder Akzeptieren eines Sockets aufgetreten ist", aber das ist in meinem Fall nicht der Fall. Weil ich es beim Verbindungsaufbau bekomme.
Was ist der Unterschied zwischen diesen beiden Ausnahmen? Eigentlich hatte ich erwartet, das ConnectException
in irgendeinem Verbindungsproblem zu bekommen (Firewall, Port, etc.)
Auch hier kam nach der gleichen Antwort, scheinbar Die Dokumente können leicht falsch interpretiert werden:
Verbindet diesen Socket mit einem angegebenen Timeout-Wert mit dem Server. EIN Timeout von Null wird als unendliches Timeout interpretiert. Die Verbindung wird dann blockiert, bis festgestellt oder ein Fehler auftritt.
Der wichtigste Teil, den ich übersehen habe, ist "ein Fehler" ... gehe zu die Quelle Ich kann sehen, wie Java connect()
tatsächlich das Linux connect()
:
d. Ich denke SocketTimeoutException
wird geworfen, wenn das Netzwerk langsam ist oder der Host überhaupt nicht reagiert. Wenn ich man connect
überprüfe, kann ich sehen, dass ECCONNREFUSED
ausgelöst werden muss, wenn "niemand auf die entfernte Adresse hört", d. H. Und ein ICMP teilt es uns mit.
Das bedeutet, dass Sie, wenn Sie wie ich versuchen, timeout
zu verwenden, um sich mit einem (localhost) Socket zu verbinden, mit dem keine Verbindung hergestellt werden konnte, Sie SOL.d sind.
ConnectException wird auf Paketfilter / Firewall usw. geworfen.
SocketTimeoutException wird ausgelöst, wenn Sie eine bestimmte Zeitüberschreitung für Ihren Socket festgelegt haben und vor dem Zeitlimit nichts empfangen wurde.
Beispiel mit einem ServerSocket
:
Wenn die ServerSocket
innerhalb von 1000 ms nichts erhalten hat, wird ein SocketTimeoutException
geworfen. Beachten Sie, dass diese Ausnahme für alle Sockets ausgelöst wird, die Timeouts verwenden, nicht nur ServerSocket
. Das bedeutet, dass ein Objekt Socket
, das ein SocketTimeoutException
auslöst, vor dem Timeout nichts vom aufgerufenen Server zurückerhalten hat.
Um das Problem zu beheben, können Sie entweder sicherstellen, dass der Server schneller reagiert, oder einen höheren Zeitüberschreitungswert festlegen.
Sie erhalten SocketTimeoutException
, wenn Sie eine Zeitüberschreitung für connect(),
angeben oder wenn Sie setSoTimeout()
für eine Socket
oder ServerSocket
bzw. eine read()
oder accept()
Zeitüberschreitung aufgerufen haben . Im Fall von connect(),
ist dies ein ernstes Problem: Was Sie versuchen, eine Verbindung herzustellen, existiert nicht oder ist hinter einer Firewall und Sie können nicht sagen, welche.
Sie erhalten connection refused
, wenn der Peer aktiv Ihre Verbindungsanforderung ablehnt, was normalerweise bedeutet, dass an dem von Ihnen angegebenen Port nichts zu hören ist. Beachten Sie, dass im Gegensatz zu einem Timeout eine Antwort empfangen wurde und negativ war.