AllesMeins: fsockopen() ignoriert timeout.

Hiho,

wieder ein Problem. Ich öffne so eine Verbindung zu einem anderen Server:

$fp = fsockopen($server, $port, $errno, $error, $timeout);

Die Variablen haben alle die richtigen Werte laut einem echo davor:

$server = "localhost";
$port = 100;
$timeout = 5;

Nun klappt das mit dem timeout nicht. Trotz dem relativ kurzen Timeout das ich angegeben habe versucht PHP knapp 20 Sekunden lang zu dem anderen Server zu verbinden, bevor es aufgibt. Wieso klappt das nicht? Irgend welche Ideen?

Grüsse

Marc

  1. Halihallo AllesMeins

    Nun klappt das mit dem timeout nicht. Trotz dem relativ kurzen Timeout das ich angegeben habe versucht PHP knapp 20 Sekunden lang zu dem anderen Server zu verbinden, bevor es aufgibt. Wieso klappt das nicht? Irgend welche Ideen?

    AFAIK entspricht Timeout unter Unix-Derivaten nicht den reellen
    Sekunden, sondern den "Prozesssekunden", also denjenigen Sekunden,
    die für diesen und nur diesen Prozess aufgewendet wurden (die CPU-
    time). Vergleiche die Laufzeit per 'ps' oder 'top' mit dem Timeout
    auf zwei Konsolen; wenn ich recht behalte, sollten diese zwei
    ziemlich genau übereinstimmen.

    Viele Grüsse

    Philipp

    1. Hello,

      <cite>
      Note: If you need to set a timeout for reading/writing data over the socket, use socket_set_timeout(), as the timeout parameter to fsockopen() only applies while connecting the socket.
      </cite>

      Wer lesen kann, ist eindeutig im Vorteil.
      Probier doch mal, den Timeout der fsockopen() sher kurz einzustellen und einen Host anszusprechen, der routingbedingt (vorher ping) nicht innerhalb des Timeout antwortet. Dann müsste es greifen.

      Wenn Du den gesamten Datenfluss kontrolliern willst, solltest Du also der obigen Empfehlung folgen. Ich bin mir aber ziemlich sicher, dass auch dieser Timeout mit jedem Byte, das gesendet wird, wieder resetted wird.

      Eine echte Flusskontrolle lässt PHP da also nicht zu, da es keine echten Interrupthandler gibt, die sich z.B. bei Intels in den Userinterrupt 1Ch einklinken könnten.

      Das könnten die[tm] bei PHP endlich mal einbauen!

      Liebe Grüße aus http://www.braunschweig.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      1. Halihallo Tom

        Probier doch mal, den Timeout der fsockopen() sher kurz einzustellen und einen Host anszusprechen, der routingbedingt (vorher ping) nicht innerhalb des Timeout antwortet. Dann müsste es greifen.

        Hm. Wer hat zufälligerweise einen Host, der einen Ping von über
        1000ms aufweist? :-)

        Eine echte Flusskontrolle lässt PHP da also nicht zu, da es keine echten Interrupthandler gibt, die sich z.B. bei Intels in den Userinterrupt 1Ch einklinken könnten.

        Nun, ich hoffe sogar, dass die[tm] das nie einbauen werden:
        Diese "Flusskontrolle" geschieht AFAIK über Signal-Handler. Bei
        einem Timeout von 1s wird intern ein sleep(1) ausgeführt, der beim
        Signal SIGHUP (also Eingang eines Blocks von Daten) abbricht. In
        modernen Betriebssystemen teilt das Betriebssystem dem Programm über
        Signale mit, dass etwas geschehen ist. Wenn nix geschieht ist das
        Programm in Schlafmodus und konsumiert keine Prozessorzeit (mehr
        Zeit für andere Programme). Und so soll es sein.

        Dein Vorschlag mit INT 1Ch:
        Nun, INT 1Ch wird alle 1/18.2 Sekunden aufgerufen. Würde sich jedes
        Programm dort einklinken um zu sehen, ob bereits Daten empfangen
        wurden, würde dies bei spätestens 5 PHP Programmen zu einer
        Endlosschleife führen, denn das "Nachsehen" dauert dann mehr als
        1/18.2 Sekunden => der nächste Aufruf geschieht bereits während der
        Aktuelle noch nichtmal abgeschlossen ist. Falls es nicht zur
        Endlosschleife führen würde, so würde doch die meiste Prozessorzeit
        für irrelevantes "Nachsehen" verpuffert. Das ist genau das, was
        moderne Betriebssysteme vermeiden wollen/sollen.

        BTW: Ich habe bei der INT 1Ch Programmierung schon ein paar mal den
        Rechner lahmgelegt, spreche also aus Erfahrung :-)

        Viele Grüsse

        Philipp

      2. Hiho,

        <cite>
        Note: If you need to set a timeout for reading/writing data over the socket, use socket_set_timeout(), as the timeout parameter to fsockopen() only applies while connecting the socket.
        </cite>

        Wer lesen kann, ist eindeutig im Vorteil.

        Es geht hier aber ums Verbinden. Ich habe einen Server der nicht antwortet und wenn ich das da oben richtig verstehe sollte PHP mit meinem Befehl genau 5 Sekunden versuchen zu diesem Server zu verbinden. Es verpulvert dabei aber mehr als 20 Sekunden, was bei einer maximalen Scriptlaufzeit von 30 Sekunden auf jedne Fall zu viel ist!

        Grüsse

        Marc