fsockopen() ignoriert timeout.
AllesMeins
- php
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
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
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
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
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