Was ist der Unterschied zwischen Verbindung und Lesezeitlimit für Sockets?


180

3 Fragen:

  1. Was ist der Unterschied zwischen Verbindung und Lesezeitlimit für Sockets?

  2. Was bedeutet das auf "unendlich" eingestellte Verbindungszeitlimit ? In welcher Situation kann es in einer Endlosschleife bleiben? und was kann auslösen, dass die Endlosschleife stirbt?

  3. Was bedeutet das auf "unendlich" eingestellte Lesezeitlimit ? In welcher Situation kann es in einer Endlosschleife bleiben? und was kann auslösen, dass die Endlosschleife stirbt?

Antworten:


227

1) Was ist der Unterschied zwischen Verbindung und Lesezeitlimit für Sockets?

Das Verbindungszeitlimit ist das Zeitlimit beim Herstellen der ersten Verbindung. dh Abschluss des TCP-Verbindungs-Handshakes. Das Lesezeitlimit ist das Zeitlimit beim Warten auf das Lesen von Daten 1 . Insbesondere wenn der Server Sekunden nach dem letzten Byte kein Byte <Zeitlimit> sendet, wird ein Lesezeitlimitfehler ausgelöst.

2) Was bedeutet das auf "unendlich" eingestellte Verbindungszeitlimit? In welcher Situation kann es in einer Endlosschleife bleiben? und was kann auslösen, dass die Endlosschleife stirbt?

Dies bedeutet, dass der Verbindungsversuch möglicherweise für immer blockiert werden kann. Es gibt keine Endlosschleife, aber der Verbindungsversuch kann durch einen anderen Thread, der den Socket schließt, entsperrt werden. (Ein Thread.interrupt()Anruf kann auch den Trick machen ... nicht sicher.)

3) Was bedeutet das auf "unendlich" eingestellte Lesezeitlimit? In welcher Situation kann es in einer Endlosschleife bleiben? Was kann dazu führen, dass die Endlosschleife endet?

Dies bedeutet, dass ein Aufruf readdes Socket-Streams für immer blockiert werden kann. Es gibt wieder keine Endlosschleife, aber die readkann durch einen Thread.interrupt()Anruf entsperrt werden, indem der Socket geschlossen wird und (natürlich) das andere Ende Daten sendet oder die Verbindung schließt.


1 - Es ist nicht ... wie ein Kommentator dachte ... die Zeitüberschreitung, wie lange ein Socket geöffnet oder inaktiv sein kann.


8

Dies sind Zeitüberschreitungswerte, die von JVM für den Aufbau einer TCP-Verbindung erzwungen werden und auf das Lesen von Daten vom Socket warten.

Wenn der Wert auf unendlich eingestellt ist, werden Sie nicht ewig warten. Es bedeutet einfach, dass JVM kein Timeout hat und das Betriebssystem für alle Timeouts verantwortlich ist. Die Zeitüberschreitungen unter dem Betriebssystem können jedoch sehr lang sein. In einem langsamen Netzwerk habe ich Zeitüberschreitungen von bis zu 6 Minuten gesehen.

Selbst wenn Sie den Timeout-Wert für Socket festlegen, funktioniert dies möglicherweise nicht, wenn das Timeout im nativen Code auftritt. Wir können das Problem unter Linux reproduzieren, indem wir eine Verbindung zu einem durch eine Firewall blockierten Host herstellen oder das Kabel am Switch abziehen.

Der einzig sichere Ansatz zur Behandlung des TCP-Timeouts besteht darin, den Verbindungscode in einem anderen Thread auszuführen und den Thread zu unterbrechen, wenn dies zu lange dauert.


"Wenn der Wert auf unendlich eingestellt ist, werden Sie nicht ewig warten." Solange es nicht um Diskussionen über die Bedeutung von "Unendlichkeit" geht, kann es sicher vorkommen, dass Sie sehr, sehr lange warten. Wir hatten hier einen Fall, in dem ein HttpURLConnection.getResponseCode()für ungefähr hängend war. eine Woche, bis wir den Prozess neu gestartet haben. Es wurde offensichtlich kein Timeout auf der JVM-Seite und auch kein Timeout auf der Linux-Betriebssystemseite festgelegt.
Tom Fink

Der letzte Absatz ist nicht korrekt. Eine Verbindung wird nach höchstens etwa einer Minute unterbrochen. Ein separater Thread ist völlig unnötig. Sie können sicher Lesevorgänge haben , die für immer laufen, wenn keine Daten vorhanden sind. Das Javadoc ist jedoch falsch, da das Standard-Verbindungszeitlimit unendlich ist. Ist es nicht.
Marquis von Lorne

1
@comeGetSome Das stimmt nicht. Sie können die Buchse für die Eingabe herunterfahren. Dadurch stößt der blockierte Lesevorgang auf das Ende des Streams.
Marquis von Lorne

@comeGetSome: Ich musste dies mithilfe eines Threads implementieren, der einen Verweis auf eine offene HTTP-URL-Verbindung enthält. Wenn der Thread die Verbindung schließt, löst der andere Thread "java.net.SocketException: Socket geschlossen" aus. Vielen Dank, Fehler JDK-8075484, dass ich das getan habe!
Fmcato

@comeGetSome Sicherlich können Sie anrufen, Socket.shutdownInput()ohne Ihre Hand gehalten zu haben? Hinweis: Diese Zeitüberschreitungen werden von TCP und nicht von der JVM erzwungen.
Marquis von Lorne
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.