socket_set_option - timeout funktioniert nicht

  • EDIT: Lösung : socket_set_option - timeout funktioniert nicht



    Ich hatte das schon vor wochen gesucht, nach stunden gefunden und getestet getestet getestet ...
    Allerdings funktioniert es nicht.
    Ich denke ich hab alles richtig gemacht, aber evtl irgentwas vergessen.


    Das grösste problem daran - wenn mal ein server, den ich anspreche, garnicht reagiert,
    dann scheint es unseren kompletten webserver zu blockieren.
    Und das möchte ich ja mit einem timeout vermeiden.


    Der code:

    PHP
    socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array("sec"=>5, "usec"=>0));


    und hier steht ja "The array will contain two keys: sec which is the seconds part on the timeout value and usec which is the microsecond part of the timeout value."
    http://de.php.net/manual/en/function.socket-get-option.php



    Was mach ich falsch oder was fehlt?

  • Kommentare unter der Beschreibung lesen hilft auch :)


    Zitat

    To set a socket timeout value (assuming you've set it blocking) use:

    PHP
    socket_set_option(
      $socket,
      SOL_SOCKET,  // socket level
      SO_SNDTIMEO, // timeout option
      array(
        "sec"=>10, // Timeout in seconds
        "usec"=>0  // I assume timeout in microseconds
        )
      );
  • Ich glaube das hatte ich auch schon gesehen und eben noch einmal ausprobiert.
    Gleiches ergebniss.


    "SO_RCVTIMEO" und "SO_SNDTIMEO" , auch als voher definiertes array (für die sec und msec), ...


    Warum kann das nicht so einfach wie bei curl sein?


    Hier nochmal der ganze code. Ich denke mal ich hab da bestimmt irgentwo anders einen fehler:

  • Ja

    Zitat


    PHP Warning: socket_connect(): unable to connect [110]: Connection timed out in ...


    und

    Zitat


    PHP Warning: socket_connect(): unable to connect [111]: Connection refused in ...


    Ist ja "aus-ge-timed", aber manche nach paar milsec (was ok ist, wenn der port nicht stimmt)
    und manche liegen deutlich über den 5 sekunden dich ich versuche einzurichten.
    Also um das nochmal aufzugreifen:


    socket_set_option SO_RCVTIMEO oder SO_SNDTIMEO funktioniert nicht.


    Mein code:


    Was mach ich falsch? Oder ist es doch ein bug? Allerdings hab ich gelesen, dass:

    Zitat

    [2005-11-03 16:02 UTC] mike@php.net
    This bug has been fixed in CVS.


    https://bugs.php.net/bug.php?id=34851


    Also egal was ich als timeout setze - wenn IP und port nicht "passen" (gegenstelle nicht antwortet ...) gibt es nach ~20 sec eine fehermeldung.
    Fehlermeldungen w#ren da:

    Zitat


    Warning: socket_connect() [function.socket-connect]: unable to connect [0]: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat. in C:\xampp\htdocs\***\***\PHP\***.php on line 12


    [30-Aug-2012 17:56:07] PHP Warning: socket_connect(): unable to connect [111]: Connection refused in /***.php on line 10


    [30-Aug-2012 17:54:08] PHP Warning: socket_connect(): unable to connect [115]: Operation now in progress in /***.php on line 10


    Komme da echt nicht weiter =/
    Sorry wenn ich das hier wieder hoch hole, aber ich komm einfach nicht zur Lösung.


    Hab jetzt mal ein testscript erstellt:


    Was mir aufgefallen ist:
    - wenn ich bei "usec" einen kleineren Wert als 1000 eingebe, dann wird er nicht übernommen:
    options:

    PHP
    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>1, 'usec'=>1)


    result:

    Zitat

    [usec] => 0


    Ausserdem bin ich über etwas komisches gestolpert:
    - wenn ich bei der IP ein Leerzeichen vor der IP eingebe, dann kommt eine andere Fehlermeldung als ohne Leerzeichen. Auch dauert der Verbindungsversuch noch länger oO?


    $IP = '8.8.8.8';
    ergibt:

    Zitat

    Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat.


    $IP = ' 8.8.8.8';
    ergibt:

    Zitat

    Der angeforderte Name ist gültig, es wurden jedoch keine Daten des angeforderten Typs gefunden.


    :huh:



    Das witzige ist - wenn ich in google nach ner Lösung suche, komm ich hier her, in meinen Thread :D
    Aber auch andere Seiten brachten bisher keinen Erfolg :(


    Was kann das sein, dass das timeout (SO_RCVTIMEO) nicht akzeptiert wird?
    Sorry wenn ich das Thema nochmal hoch hole.
    Aber ich hab immernoch keine Lösung gefunden.
    Es wird einfach kein Timeout übernommen. :(


    Das Problem an der Sache ist einfach, dass das Script für 20-30 sec still steht.



    Roland hat mich auf was gebracht:

    PHP
    echo "<pre>";
    print_r(ini_get_all());



    Selbst wenn ich den Wert überschreibe ( ini_set("default_socket_timeout", 2); ) wird es nicht übernommen.
    Ich glaub aber auch, dass der Wert nicht für mein Vorhaben passt, weil:
    default_socket_timeout:

    Zitat

    Standardzeitbeschränkung für Socket-basierende Streams in Sekunden.


    Das eine ein "type: resource - stream", das andere "type: resource - socket".


    Hoffe also immernoch, dass jemand eine Idee hat :S
    Endlich die Lösung gefunden.
    Der Punkt ist, dass socket_set_option() SO_RCVTIMEO und SO_SNDTIMEO einfach keine Wirkung zeigen.
    Aber mit socket_select() kann man ein funktionierendes Timeout setzen.
    Dabei MUSS aber socket_set_nonblock() gesetzt werden.


    (funktionierender) Code:


    EDIT:
    Auf Windows Systemen funktioniert das Timeout via socket_select()
    Aufm "echten" Server kann er allerdings wieder blockieren -- socket_select() "steht" still und ignoriert das gegebene Timeout.


    Lösung dafür: das timeout (hier $timeout_select genannt) auf 0 (Zahl null) setzen. socket_select() blockiert dann nicht mehr, und das Timeout wird über $timeout_hard geregelt.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!